I'm trying to make one class which requires member variables to be initialized first. I know why this happens, but is there a way around this?
Current print order:
second
first
Wanted print order:
first
second
#include <iostream>
struct A {
A() {
std::cout << "first" << '\n';
}
};
struct B {
B() {
std::cout << "second" << '\n';
}
};
struct C : public B {
C() : a(), B() {
}
A a;
};
int main() {
C c;
return 0;
}
Stick your members that need initializing first in a struct and inherit privately from that, before B.
struct A {
A() { std::cout << "first" << '\n'; }
};
struct B {
B() { std::cout << "second" << '\n'; }
};
struct Members { A a; };
struct C : private Members, public B {
C() : Members(), B() {}
};
int main() {
C c;
}
The downside with this is that there is no way to avoid exposing the "member struct" to the outside world, but that shouldn't be a problem in practice.
In C++ base classes will be initialized before any member variables of a derived class.
The best recourse given the information you've provided is to prefer composition over inheritance:
struct A {
A() {
std::cout << "first" << '\n';
}
};
struct B {
B() {
std::cout << "second" << '\n';
}
};
struct C {
A a;
B b;
};
This will exhibit the desired behavior
Make A a needed reference for C:
#include <iostream>
struct A {
A() {
std::cout << "first" << '\n';
}
};
struct B {
B() {
std::cout << "second" << '\n';
}
};
struct C : public B {
C(const A& a) : _A(a), B() {}
const A& _A;
};
int main() {
A a;
C c(a);
return 0;
}
Related
Full disclaimer, this is homework - not graded, just given to students so we can practice.
I'm asking for help, because we won't get an answer and I just want to know how to solve it.
What I can do is define structures B and C. Their interface has to be "like A's interface, with modifications so it works correctly".
I can't add any new methods. I also can't change anything in struct A.
This is the code:
#include <iostream>
struct A;
struct B;
struct C;
struct A {
A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
int main(){
C c;
}
And the desired output is:
A::A()
A::A()
B::B()
A::A()
A::A()
B::B()
A::A()
C::C()
What I tried to do so far:
First I started like this, just to check things out:
struct B : public A {
B() : A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct C : public B {
C() : B() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
Which gave me:
A::A()
B::B()
C::C()
So I tried to get first C, then A, then B, then A (desired output from the bottom):
struct B : public virtual A {
B() : A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct C : public B, public A {
C() : A(), B() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
But of course this didn't work. (warning: direct base āAā inaccessible in āCā due to ambiguity)
Adding virtual keyword like below gave me again C, B then A, from the bottom:
struct B : public virtual A {
B() : A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct C : public virtual A, public B {
C() : A(), B() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
If I want to get C, then A I have to do the following (but then there will be no B)
struct C : public virtual A {
C() : A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct B : public virtual A, public C {
B() : C(), A() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
I also have no idea how could I get A::A() twice in a row.
I just want to understand how this should work, but if you still feel like you don't want to help me with a solution, then please leave me some tips.
I do not see a restriction in the exercise on use of class members:
struct A
{
A() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
struct B : A
{
B() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
struct C
: B
, A
{
C() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
B b;
A a;
};
UPDATE
The desired output had changed since my first answer was posted. So previous answer had become wrong. But now you see the point - you can use composition and copy A a; to B definition and remove A inheritance from C definition.
You can do something like:
struct B : A { //inherit from A
B() {
A();
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
struct C : B { //inherit from B
C() {
B(); //anonymous B object
A(); //anonymous A object
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
Running sample
Why does the d instance have different this addresses? Someone told me that in OOP languages, a derived class is simply all the members of the base class, followed by members of its own.
#include <iostream>
#include <memory>
struct A
{
int member;
};
struct B : public virtual A
{
void print_b() { std::cout << static_cast<void*>(this) << " " << static_cast<void*>(&this->member) << std::endl; }
};
struct C : public virtual A
{
void print_c() { std::cout << static_cast<void*>(this) << " " << static_cast<void*>(std::addressof(member)) << std::endl; }
};
struct D : public B, public C
{
void print()
{
print_b();
print_c();
}
};
int main()
{
D d;
d.print();
}
Online outputs:
0x700af9347b90 0x700af9347ba0
0x700af9347b98 0x700af9347ba0
Because the B and C base sub objects are distinct objects in relation to each other and cannot share an address.
Empty base sub objects could be exempted from the requirement of having a unique address, but B and C are not empty.
consider following code:
I know that when you create an object of class C first member variables will be constructed then order of construction will be abc and deconstruction CBA . now question is that if there is a way to call constructor of class C sooner than member variables ? to have order of cab and for deconstruction BAC
how i could change order that way first constructor of class be called then member variables.
#include <iostream>
#include <exception>
class A {
public:
A() {
std::cout << 'a';
}
~A() { std::cout << 'A'; }
};
class B {
public:
B() { std::cout << 'b'; }
~B() { std::cout << 'B'; }
};
class C {
public:
C() {
std::cout << 'c';
}
~C() { std::cout << 'C'; }
A m_a ;
B m_b;
};
void foo() { C c; }
int main() {
try {
foo();
}
catch (std::exception &) {
std::cout << "catch";
}
}
More of a workaround than actually breaking construction order (which isn't possible). Store the members by smart pointer.
class C {
public:
C() {
std::cout << 'c';
m_a = std::make_unique<A>();
m_b = std::make_unique<B>();
}
~C() {
m_b.reset();
m_a.reset();
std::cout << 'C';
}
std::unique_ptr<A> m_a;
std::unique_ptr<B> m_b;
};
The instances of the actual objects you care about can now be created at the end of C's constructor. Of course, you pay for it by doing dynamic memory allocation.
Another solution can be to use aligned storage and placement new construction:
class C {
public:
C() {
std::cout << 'c';
new(&m_a) A;
new(&m_B) B;
}
~C() {
m_b.~B();
m_a.~A();
std::cout << 'C';
}
std::aligned_storage<sizeof(A), alignof(A)>::type m_a;
std::aligned_storage<sizeof(B), alignof(B)>::type m_b;
};
But either way you have to be very careful and follow to rule of three/five.
Or simply:
class C {
public:
A *m_a;
B *m_b;
C() {
std::cout << 'c';
m_a = new A;
m_b = new B;
}
~C() {
delete m_b;
delete m_a;
std::cout << 'C'; }
};
Use smart pointers to ensure exception safeness
I'm playing with construting/destructing object. Here is what I've tried http://coliru.stacked-crooked.com/a/ff17cc5649897430:
#include <iostream>
struct B{
B(){ std::cout << "B()" << std::endl; }
B(int){ std::cout << "B(int)" << std::endl; }
};
struct A : virtual B
{
int B;
A(int a) : B(a) { std::cout << "A(int)" << std::endl; }
} a(10);
int main()
{
}
The program output is
B()
A(int)
Why? I explicitly specify the constructor of the class B to be invoked in the ctor-initializer.
The B(a) is constructing the B member variable. Name your variables better and you'll see what you want to see.
I'm trying to find my way around. I have two classes, A and B, where B inherits from A.
There are also two overloaded functions for A and B, that act on them in two different ways.
Now call these functions from a class function like this:
#include <iostream>
struct A;
struct B;
void f(A a);
void f(B b);
struct A {
int i;
A(): i(0) {};
void thisf() { f(*this); }
};
struct B: public A {
int j;
B(): j(1) {};
void thisf() { f(*this); }
};
void f(A a) { std::cout << a.i << std::endl; }
void f(B b) { std::cout << b.i << " " << b.j << std::endl; }
int main() {
A a;
B b;
a.thisf();
b.thisf();
return 0;
}
My question is: since A::thisf() and B::thisf() are the same (and will stay the same for more subclasses), is there a way how I can omit B::thisf() while still having the same functionality?
The expected output should look like:
0
0 1
More detail why I try to do this: I want to provide some custom render functionality to different kinds of data without bloating the class with render logic and have a separate render class with some state variables. But I don't want to give up the possibility to write
b.render()
in some situations. In my class definitions I want to spare every line I can.
I got the idea in this thread: https://gamedev.stackexchange.com/questions/63912/visitor-pattern-vs-inheritance-for-rendering
In your proposed problem you claim the need for a method in A and B that is not polymorphic and yet exhibits different behaviour in the two classes (linked by inheritance) with the same signature.
In addition, the method defers to a free function found by ADL (good!).
So... my question to you is this. If you already have the guarantee of a free function called f(A|B), why not simply document that as the interface?
If you insist on having thisf() you are causing yourself a problem because the inheritance relationship will cause B's thisf() to be ambiguous with A's. This can be solved with polymorphism (as per the other answer) but since you're rejecting that, you are are left with few options other than to eliminate the logically redundant thisf() altogether.
in any case, this code will do exactly as you want:
#include <iostream>
struct A;
struct B;
void f(A a);
void f(B b);
struct common_interface {
virtual void thisf() = 0;
};
template<class Host, class Base>
struct common_interface_impl : Base {
virtual void thisf() {
f(static_cast<Host&>(*this));
}
};
struct A : common_interface_impl<A, common_interface>
{
int i;
A(): i(0) {};
};
struct B: common_interface_impl <B, A>
{
int j;
B(): j(1) {};
};
void f(A a) { std::cout << a.i << std::endl; }
void f(B b) { std::cout << b.i << " " << b.j << std::endl; }
int main() {
A a;
B b;
a.thisf();
b.thisf();
return 0;
}
#include <iostream>
struct A {
int i;
A(): i(0) {};
virtual ~A() {};
virtual void thisf() { std::cout << i << std::endl; }
};
struct B: public A {
int j;
B(): j(1) {};
void thisf() { A::thisf(); std::cout << j << std::endl; }
};
void f( A* a )
{
a->thisf();
}
int main() {
A* a = new A();
A* b = new B();
f( a ); f( b );
delete a; delete b;
return 0;
}