Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
#include <iostream>
using namespace std;
class Base {
int x;
public:
Base() : x() {}
Base(int x) : x(x) {}
virtual void print() const {
cout << x << endl;
}
};
on Derived(int x, int y) : x(x), y(y) {}, Compiler said must usd "default constructor", but i'd thought that already made, and wonder why default constructor is needed.
class Derived : public Base {
int x, y;
public:
Derived(int x, int y) : x(x), y(y) {}
void print() const override {
cout << x << ", " << x << endl;
}
};
int main() {
// All data members of Base and Derived classes must be declared
// as private access types
Base* p1 = new Derived(10, 20); // (x, y)
Base* p2 = new Base(5); // (x)
p1->print(); // prints 10, 20
p1->Base::print(); // prints 10
}
second in this problem,
p1->Base::print(); // prints 10
p1->Base::print() must print 10, but it didn't work. How can I print 10?
Your base class is missing a virtual destructor so trying to delete p1; will cause undefined behavior.
Derived has 2 x member variables. Base::x and Derived::x. You most probably only want one. This also explains why p1->Base::print() doesn't do what you want. Base::x is 0 and Derived::x is 10.
Base::x is private so the print function in Derived should probably rely on Base::print to print it.
Example:
The base class here has a virtual destructor and the print function takes an ostream& so that it can print to any ostream (like std::cout or a file stream):
class Base {
int x;
public:
Base() : x() {}
Base(int x) : x(x) {}
virtual ~Base() = default;
virtual void print(std::ostream& os = std::cout) const {
os << x;
}
};
Derived here does not add an x member variable, but initializes Base with the x value supplied to its constructor. The print function simply calls the base class print:
class Derived : public Base {
int y;
public:
Derived(int x, int y) : Base(x), y(y) {}
void print(std::ostream& os = std::cout) const override {
Base::print(os); // calls `print` in the base class
os << ' ' << y; // and adds its own output
}
};
You can also add an operator<< overload to make printing easier. Note that you only need one for the base class. It will call the print function in the most derived class:
std::ostream& operator<<(std::ostream& os, const Base& b) {
b.print(os);
return os;
}
The main function then becomes:
int main() {
Base* p1 = new Derived(10, 20); // (x, y)
Base* p2 = new Base(5); // (x)
std::cout << *p1 << '\n'; // 10 20
std::cout << *p2 << '\n'; // 5
p1->Base::print(); // 10
delete p1;
delete p2;
}
Or better, use smart pointers so that you don't forget to delete what you've allocated:
int main() {
std::unique_ptr<Base> p1 = std::make_unique<Derived>(10, 20);
std::unique_ptr<Base> p2 = std::make_unique<Base>(5);
std::cout << *p1 << '\n'; // 10 20
std::cout << *p2 << '\n'; // 5
p1->Base::print(); // 10
}
Demo
Related
This question already has answers here:
How can I initialize base class member variables in derived class constructor?
(7 answers)
Closed 24 days ago.
#include <iostream>
class A {
public:
const int HP = 200;
A(){
std::cout << this->HP << std::endl;
}
};
class B : public A {
public:
B();
};
Constructing a B object will construct the A potion first.
I expect to reinitialize HP so that B() can print new HP.
Is this feasible for a base class const member ?
I need a member shared between base and child but to be constant in one instance of class, any suggestions?
You can add a constructor to A (and if needed also to B) that accepts the value for the const int member.
Then when you invoke A constructor from B constructor via the initializer list, you can pass this const value to the base.
Code example:
#include <iostream>
class A {
public:
const int HP = 200;
A() {
std::cout << this->HP << std::endl;
}
//----vvvvvv----vvvvvv--
A(int hp) : HP(hp) {
std::cout << this->HP << std::endl;
}
};
class B : public A {
public:
B() {};
//----vvvvvv----vvvvv--
B(int hp) : A(hp) {}
};
int main()
{
B b1;
B b2{ 99 };
}
Output:
200
99
Note: B can also be left as is (without an additional constructor), and pass the required const value to the base.
This question already has answers here:
no default constructor exists for class
(5 answers)
Closed 1 year ago.
Why do I get the error "No default constructor exists for class "Sub", even though I have the constructor for Sub class"
class Base{
private:
int x;
public:
Base(int number)
{
x = number;
}
virtual void print(void) = 0;
};
class Sub: public Base{
public:
Sub(int x): Base(x) {
}
void print()
{
cout << "Testing" << endl;
}
};
A default constructor is one taking NO arguments. A default constructor is one which requires no provided arguments.
Base() and Base(args = default) are both considered default constructors, as no arguments are required. Please note the second one is Pseudo Code.
class Base{
private:
int x;
public:
Base(int number)
{
x = number;
}
virtual void print(void) = 0;
};
class Sub: public Base{
public:
Sub(int x): Base(x) {
}
void print()
{
cout << "Testing" << endl;
}
};
Your code definitely does not have a default constructor.
Declaring a constructor automatically disables the compiler-created default contructor.
More info:
https://en.cppreference.com/w/cpp/language/default_constructor
https://www.geeksforgeeks.org/constructors-c/
https://www.ibm.com/docs/en/zos/2.2.0?topic=only-default-constructors-c
https://www.w3schools.com/cpp/cpp_constructors.asp
https://learn.microsoft.com/en-us/cpp/cpp/constructors-cpp
https://www.learncpp.com/cpp-tutorial/constructors/
I'm new to polymorphism and I'm trying to learn how this exactly works .
I want for example to get the print() function of class Y and use it in the base class .
Is this possible to do ?
class A
{
public:
A() = default;
virtual void print()
{
//Is it possible to get the print() function of class Y here ?
};
};
class B : public A
{
public:
B() = default;
void print(){ std::cout << "B " << std::endl;}
};
class C : public A
{
public:
C() = default;
void print(){ std::cout << "C " << std::endl;}
};
class Y : public C , public B
{
public:
Y() = default;
void print()
{
B::print();
C::print();
}
};
int main()
{
A a;
a.print();
return 0;
}
Your main() is creating an A object directly, not a Y object. That is why you are not seeing the output you want. Polymorphism only works when accessing derived class objects via base class pointers/references, eg:
int main()
{
Y y;
A *a = static_cast<C*>(&y);
a->print();
return 0;
}
int main()
{
Y y;
A &a = static_cast<C&>(y);
a.print();
return 0;
}
The reason for the type cast is becauseY has 2 A portions, one from B and one from C, so you have to help the compiler a little by specifying which A you want to point to.
casting shared pointer from B class to A class is not working the console output isn't 12 it's (it outputs A's x but i want B's x)(probably an other memory address). what's wrong with my code
#include <iostream>
#include <memory>
class A
{
public:
int x;
};
class B : public A
{
public:
B(){}
B(const B*){}
int x = 12;
};
std::shared_ptr<A> create()
{
return std::make_shared<B>(new B);
}
int main(){
std::shared_ptr<A> p;
p = create();
std::cout << p->x << std::endl;
std::cin.get();
return 0;
}
A::x and B::x are different objects. Variable access is never polymorphic in C++, so when you access p->x, you're accessing A::x. A::x was never initialized though, so the behavior of your program is undefined.
You need to either have your derived class's constructor initialize the base class's object or delegate that responsibility to the base class's constructor:
class A
{
public:
A(int x) : x{x} {}
int x;
};
class B : public A
{
public:
B() : A{12} {}
};
Live Demo
Alternatively you could wrap x in a virtual accessor method:
class A
{
public:
virtual ~A() = default;
virtual int x() const = 0;
};
class B
{
public:
int x() const override
{
return x_;
}
private:
int x_ = 12;
};
Live Demo
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Composition is kinda like inheritance but instead of inheriting the super-class, the super-class is a data member of the sub-class.
In such cases, how do you call the parameterized constructor of the super-class whenever an object of the sub-class is created (I know that we can't use the terms sub and super class here but it's just for clarity).
class A {
int a;
public:
A() {
cout << "\nDefault constructor of A called.\n";
a = 0;
}
A(int x) {
cout << "\nParameterized constructor of A called.\n";
a = x;
}
int getA() {
return a;
}
};
class B {
A o;
int b;
public:
B() {
cout << "\nDefault constructor of B called.\n";
b = 0;
}
B(int x) {
cout << "\nParameterized constructor of B called.\n";
b = x;
}
int getB() {
return b;
}
};
class C {
int c;
public:
A o;
C() {
cout << "\nDefault constructor of C called.\n";
c = 0;
}
C(int x) {
cout << "\nParameterized constructor of C called.\n";
c = x;
}
int getC() {
return c;
}
};
B and C are two different versions of composition. How to call the parameterized constructor of A in either of them. I mean, please modify the class definitions accordingly.
Using member initializer lists:
class C
{
private:
A a;
int b;
public:
C(int x) :
a(x), // <- Calls the `A` constructor with an argument
b(x) // <- Initializes the `b` member to the value of `x`
{ }
};
B(int x) : o(x) {
cout << "\nParameterized constructor of B called.\n";
b = x;
}
Note the intialization of member variable o using the parameter passed into B's constructor.