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.
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.
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
In this inheritance program I create 2 classes which A is parent and B is child class . and i crate cons of both classes and also use
Destructor, and both classes have tow objects . # MY question is that
when my program is run then its output show 2 Destructor of class a
why ?
#include <iostream>
using namespace std;
class A
{
int a;
public:
A(int a1) // cons(A)
{
a = a1;
}
A() {} // Dis(A)
~A() { cout << "A Disturctor"<< endl; }
};
class B : public A // inheritance
{
int b;
public:
B(int b1) // cons (A)
{
b = b1;
}
~B() { cout << "B Disturctor" << endl; } // Dis(B)
};
int main()
{
A hamza(1);
B Ramza(4);
return 0;
}
Output:
B Disturctor
A Disturctor1
A Disturctor2
The first "A Disturctor" is for object "A hamza(1)".
The second "A Disturctor" is for object "B Ramza(4)"
Since B inherits from A, when object of class B is destroyed, destructor of both class B and class A are called.
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.
Lets say I have the following code in what we expect to become the next C++ standard:
int f(int x)
{
std::cout << x;
return x * x;
}
struct A
{
A(int x) : m_x(x) {}
int m_x;
};
struct B : A
{
using A::A;
B() : m_y(f(m_x)) {}
int m_y;
};
int main()
{
B(5);
}
Would this call the default constructor of B and print out 5 and set m_y = 25? Or will the default constructor of B not run, and leave m_y uninitialized?
And if the latter, what is the rationale behind not calling the B default constructor? It is quite clear that the A(int) B inherits only initialises A, and leaves B in an indeterminate state. Why would C++ choose undefined behaviour over simply calling the default constructor of B()? It largely defeats the purpose of the inheriting constructors feature.
Edit:
Perhaps this should be allowed:
using A::A : m_y(...) { std::cout << "constructing..." << std::endl; ...; }
using A::A; implicitly declares B(int) in the derived class. That is it.
The rest of your program should not work as you expect. Because you're invoking B(int) with B(5), and that leaves m_y uninitialized.
See this example from Bjarne Stroustrup's site:
struct B1 {
B1(int) { }
};
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test()
{
D1 d(6); // Oops: d.x is not initialized
D1 e; // error: D1 has no default constructor
}
http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting
Another example from the same link:
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x{0}; // note: x is initialized
};
void test()
{
D1 d(6); // d.x is zero
}