c++ [diamond configuration] How to initialize with inheritance? - c++

I apologize if my question is dumb but i'm a beginner in c++. I'm working on diamond inheritance and i would like to know if it is possible to choose the specific parent class which will initilize an attribute for the child class.
To sum up, i would like this code to output B
Thank you for your answers !
PS: i'm working with c++98
#include <iostream>
class A
{
protected:
char m_char;
public:
A(): m_char('A'){};
char getChar(){return m_char;};
~A(){};
};
class B : virtual public A
{
private:
public:
B() {m_char = 'B';};
~B(){};
};
class C : virtual public A
{
private:
public:
C() {m_char = 'C';};
~C(){};
};
class D : public B, public C
{
private:
public:
D() {m_char = B::m_char;};
~D(){};
};
int main(void)
{
D d;
std::cout << d.getChar() << std::endl;
}

Virtual base classes are initialized In depth-first, left-to-right order. So you would need to name B second in your inheritance for D to call its constructor last and thus setting the variable to B at the end.
class D : public C, public B

m_char = B::m_char; is self assignment (there is only one m_char).
In virtual inheritance, it is the most derived class which initialize the virtual class (body does assignment).
How about being explicit in construction:
#include <iostream>
class A
{
protected:
char m_char;
public:
A() : m_char('A') {}
char getChar() const { return m_char; }
virtual ~A() {}
};
class B : virtual public A
{
public:
B() : A('B') {}
};
class C : virtual public A
{
public:
C() : A('C') {}
};
class D : public B, public C
{
public:
D() : A('B'), B(), C() {}
};
int main()
{
D d;
std::cout << d.getChar() << std::endl;
}

Related

c++ how do i get a specific value from a specific inherited class

I'm learning C++ OOP. I don't understand a principle, and I don't know what to google to find an answer.
If I have this:
#include <iostream>
class A
{
public:
int a;
A() : a(1){}
};
class B : virtual public A
{
public:
B() {this->a = 2;}
};
class C : virtual public A
{
public:
C() {this->a = 3;}
};
class D : public B, public C
{
public:
D() {this->a = B::a;}
};
int main()
{
D test;
std::cout << test.a << std::endl;
}
I expect the output to be 2 since I want the value of the inherited B class in the D class. It seems to me like the value of the C class is taken, because that constructor gets called last and overwrites the B::a value, is that right?
How would I go about getting values from the B class inside the D class?

In C++, do derived classes need its own constructors defined if it only requires constructors from the base class? [duplicate]

While working with templates I ran into a need to make a base class constructors accessible from inherited classes for object creation to decrease copy/paste operations.
I was thinking to do this through using keyword in same manner with functions case, but that not work.
class A
{
public:
A(int val) {}
};
class B : public A
{
};
class C : public A
{
public:
C(const string &val) {}
};
class D : public A
{
public:
D(const string &val) {}
using A::A; // g++ error: A::A names constructor
};
void main()
{
B b(10); // Ok. (A::A constructor is not overlapped)
C c(10); // error: no matching function to call to 'C::C(int)'
}
So my question: Is there any way to import a base class constructors after new ones in inherited class been declared?
Or there is only one alternative to declare new constructors and call a base ones from initializer list?
Yes, Since C++11:
struct B2 {
B2(int = 13, int = 42);
};
struct D2 : B2 {
using B2::B2;
// The set of inherited constructors is
// 1. B2(const B2&)
// 2. B2(B2&&)
// 3. B2(int = 13, int = 42)
// 4. B2(int = 13)
// 5. B2()
// D2 has the following constructors:
// 1. D2()
// 2. D2(const D2&)
// 3. D2(D2&&)
// 4. D2(int, int) <- inherited
// 5. D2(int) <- inherited
};
For additional information see http://en.cppreference.com/w/cpp/language/using_declaration
Prefer initialization:
class C : public A
{
public:
C(const string &val) : A(anInt) {}
};
In C++11, you can use inheriting constructors (which has the syntax seen in your example D).
Update: Inheriting Constructors have been available in GCC since version 4.8.
If you don't find initialization appealing (e.g. due to the number of possibilities in your actual case), then you might favor this approach for some TMP constructs:
class A
{
public:
A() {}
virtual ~A() {}
void init(int) { std::cout << "A\n"; }
};
class B : public A
{
public:
B() : A() {}
void init(int) { std::cout << "B\n"; }
};
class C : public A
{
public:
C() : A() {}
void init(int) { std::cout << "C\n"; }
};
class D : public A
{
public:
D() : A() {}
using A::init;
void init(const std::string& s) { std::cout << "D -> " << s << "\n"; }
};
int main()
{
B b; b.init(10);
C c; c.init(10);
D d; d.init(10); d.init("a");
return 0;
}
No, that's not how it is done. Normal way to initialize the base class is in the initialization list :
class A
{
public:
A(int val) {}
};
class B : public A
{
public:
B( int v) : A( v )
{
}
};
void main()
{
B b(10);
}
You'll need to declare constructors in each of the derived classes, and then call the base class constructor from the initializer list:
class D : public A
{
public:
D(const string &val) : A(0) {}
D( int val ) : A( val ) {}
};
D variable1( "Hello" );
D variable2( 10 );
C++11 allows you to use the using A::A syntax you use in your decleration of D, but C++11 features aren't supported by all compilers just now, so best to stick with the older C++ methods until this feature is implemented in all the compilers your code will be used with.
class A
{
public:
A(int val) {}
A(string name) {}
};
class B : public A
{
using A::A;
};
Addition to other answers, in case there are several constuctors with the base class, and you just want to inherit some of them, you can delete the unwanted.
class B : public A
{
using A::A;
B(string) = delete;
};
Here is a good discussion about superclass constructor calling rules. You always want the base class constructor to be called before the derived class constructor in order to form an object properly. Which is why this form is used
B( int v) : A( v )
{
}

Access inner class private variable in outer class

//In file1.hpp
class A
{
protected:
class B
{
public:
B () {};
};
};
// In file2.hpp
class C
{
public:
void getValue()
{
D obj; ---- error: no matching function for call to D
printf("%d\n",obj.c);
}
class D : public A::B
{
friend class C; -- I tried writing this but still no luck.
public:
D(int a, int b) : c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; int d;
};
class E : public D
{
E() : D(1,2) {}
virtual ~E() {}
};
}
int main()
{
C::E obj;
}
In the public function, getValue I want to access the private member variables of the class D which are (c and d). How can I do that? I tried putting "friend class C" inside class D and then tried creating an object of class D inside getValue function but instead of getting a value like c=5 or d=6, I always get 0.
If I print the value in the following area, I get the correct value. I won't be able to show you how getValue is called but just imagine that it is called somehow. I just need to print c,d in that.
D(int a, int b)
: c(a), d(b) {};
EDIT: At the time of instantiation in getValue, I do something like this
D obj; --- error: no matching function for call to D
Let take the following example:
#include <iostream>
//In file1.hpp
class A
{
protected:
class B
{
public:
B () = default;
};
friend class C; // <-- bad idea
};
// In file2.hpp
class C
{
public:
void getValue()
{
// Creating an object E?
E objE;
// Access c and d
std::cout << "c:" << objE.c << ", d:" << objE.d << std::endl;
}
class D : public A::B // <-- bad idea?
{
public:
D(int a, int b): c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; // dangerous to not initialize basic types
int d;
friend class C; // <-- bad idea
};
class E : public D
{
public:
E() : D(1,2) {}
virtual ~E() {}
};
};
int main()
{
C objC;
objC.getValue();
}
( you can run it here: https://onlinegdb.com/hNfm7Pvg0f )
First is, to have an instance of E to access in C::getValue, so I instantiated an object.
private and protected indicate that those properties and methods are not available publicly (encapsulation) and that is exactly what you are trying to do. You can make exceptions with friend keyword, but that is rarely a good idea (I probably use it twice in my 20 years carrier). But hey! it works.

How to access derived data from base class C++

class B :I'm in this type of scenario in my project, where I'm in x()function of base class A and need to access the data y from derived class C.
I have declared the object of derived class C and using obj_c i got to the x() function
class A
{
private :
public :
//.....
void x()
{
cout << y ;
}
//.....
};
class B : public A
{
public :
//.....
protected :
//.....
private :
//.....
};
class C : public B
{
public :
//.....
protected :
int y = 10 ;
private :
//.....
};
int main()
{
C obj_c ;
obj_c.x();
}
Place the declaration of y inside the base class. After all, the way you've written your code, A needs to contain a y in order to function.
The derived class can then assign the value by passing it up to A at construction.
class A {
public:
void x() { cout << y; };
protected:
A(int value) : y(value) {}
int y;
}
class B : public A
{
protected:
B(int value) : A(value) {}
}
class C : public B
{
public:
C() : B(10) {}
}
As C inherits from B and B inherits from A, then make function virtual in class. implement it in C and call it directly.
The idea of a base class is that A might be used even if C didn't exist. So where is A going to get y?
What you do in those cases is the Template Method design pattern:
A assumes that inheriting classes will provide a y by requiring that they implement a get_y() method:
#include <iostream>
class A
{
private :
protected:
virtual int get_y() = 0;
public :
//.....
void x()
{
std::cout << get_y() << std::endl;
}
//.....
};
class B : public A
{
public :
//.....
protected :
//.....
private :
//.....
};
class C : public B
{
public :
//.....
protected :
int get_y()
{
return 10;
}
private :
//.....
};
int main()
{
C obj_c ;
obj_c.x();
}

Accessing the variable of the base class from derived class in Hybrid Inheritance

I have written a C++ program.
#include <iostream>
#include <string>
using namespace std;
class A
{
int a;
public:
void read()
{
cin>>a;
}
};
class B:public A
{
public:
B()
{ }
};
class C:public A
{
public:
C()
{}
};
class D:public B,public C
{
public:
void display()
{
cout<<a<<endl;
}
};
void main()
{
A a1;B b1;C c1;
D d1;
d1.display();
}
I get a message saying there is ambiguity. B is inheriting A.. So B class would inherit item 'a' from class A. Also, C class will inherit item 'a' from class A. Now if im trying to inherit both B and C classes in class D, which item 'a' will i be able to access ?? from class B or from class C ?? Is there any way where i can remove the ambiguity .?
You can fix your ambiguity problem by using one of the following options:
Be explicit about the base class
Use B as the explicit base class
void display()
{
cout<< B::a <<endl;
}
or use C as the explicit base class.
void display()
{
cout<< C::a <<endl;
}
Use virtual inheritance
Change B and C to use virtual inheritance.
class B: virtual public A
{
public:
B() {}
};
class C: virtual public A
{
public:
C() {}
};