I have 3 classes, A,B, and C.
Edited code.
#include <iostream>
class A {
public:
virtual void print() {
std::cout << "A" << std::endl;
}
A() : x(0) {} // constructor
void SetX (int tmp){
x = tmp;
}
void printX() {
std::cout << "x = " << x << std::endl;
}
private:
int x;
};
class B : public A {
public:
virtual void print(){
std::cout << "B" << std::endl;
}
B(int tmp) : A() {
SetX(tmp);
}
};
class C : public B {
public:
virtual void print(){
std::cout << "C" << std::endl;
}
C(int tmp) : B(tmp) {
std::cout << "Debug print" << std::endl;
}
};
int main() {
B* b = new B(1);
C* c = new C(2);
b->print();
b->printX();
c->print();
c->printX();
return 0;
}
print for b->printX = 1
and for c->printX = 0
when creating object B everything is work just fine.
but when creating object C the default value of class A (var x) is still 0 (default value).
i added debug line inside the constructor of class C, but i didnt see it in logs, looks like the constructor is not running. i did the same thing in the constructor of class B when creating only object C and i didnt see any debug print too.
There no any compiling error for this code. build finish successfully.
The following is legal and working C++. Your code was not legal C++.
I added a void printX() method to class A to illustrate the example.
#include <iostream>
class A {
public:
virtual void print() {
std::cout << "A" << std::endl;
}
A() : x(0) {} // constructor
void SetX (int tmp){
x = tmp;
}
void printX() {
std::cout << "x = " << x << std::endl;
}
private:
int x;
};
class B : public A {
public:
virtual void print(){
std::cout << "B" << std::endl;
}
B(int tmp) : A() {
SetX(tmp);
}
};
class C : public B {
public:
virtual void print(){
std::cout << "C" << std::endl;
}
C(int tmp) : B(tmp) {
std::cout << "Debug print" << std::endl;
}
};
int main() {
B* b = new B(1);
C* c = new C(2);
b->print();
b->printX();
c->print();
c->printX();
return 0;
}
Related
When I try to run this code:
class A : public enable_shared_from_this<A> {
public:
A() {
cout << "A::A()" << endl;
};
virtual ~A() {
cout << "A::~A()" << endl;
};
virtual void func() {
cout << "A::func" << endl;
auto ptr = shared_from_this();
ptr->dosomething();
}
virtual void dosomething() {
cout << "A::dosomething" << endl;
}
};
class B : public A {
public:
B() {
cout << "B::B()" << endl;
};
~B() {
cout << "B::~B()" << endl;
};
void func() override {
cout << "B::func" << endl;
A::func();
}
void dosomething() override {
cout << "B::dosomething" << endl;
}
};
int main() {
shared_ptr<B> pb = make_shared<B>();
//shared_ptr<A> pa = make_shared<A>();
pb->func();
}
The result I get is:
A::A()
B::B()
B::func
A::func
B::dosomething
B::~B()
A::~A()
The call chain is B::func->A::func->ptr->dosomething, this indicates that the return value of shared_from_this() is a shared_ptr<B>.
Why is the result of calling shared_from_this() not shared_ptr<A>?
i have troubles with some methods after inherit.
It's hard (for me) to say where exactly problem is but i will try to expose this by example.
Minimal code:
#include <iostream>
class A
{
public:
A() {};
A(int x):val(x)
{
std::cout << "A constructor work" << std::endl;
}
int get()
{
std::cout << "Get A work" << std::endl;
return val;
}
protected:
int val;
};
class B: protected A
{
public:
B(int x) :A(x)
{
std::cout << "B constructor work" << std::endl;
test();
}
int get()
{
std::cout << "Get B work" << std::endl;
return A::get();
}
protected:
void test()
{
if (A::val == 0)
{
std::cout << "Test B work" << std::endl;
A::val = 1;
}
}
};
class C : protected A
{
public:
C() {};
C(int x) :A(x)
{
std::cout << "C constructor work" << std::endl;
test();
}
int get()
{
std::cout << "Get C work" << std::endl;
return A::get();
}
protected:
void test()
{
std::cout << "Test C work" << std::endl;
if (A::val != 0)
{
A::val += 2;
}
}
};
class D : private B, private C
{
public:
D(int x):B(x)
{
std::cout << "D constructor work" << std::endl;
C::test();
}
int get()
{
std::cout << "Get D work" << std::endl;
return B::get();
}
};
int main()
{
D d(0);
std::cout << d.get() << std::endl;
}
Output:
**A constructor work
B constructor work
Test B work
D constructor work
Test C work
Test C extra work
Get D work
Get B work
Get A work
1**
I expect val = 3 in the end, but it dont work like that.
I would be particularly grateful for your detailed reply.
Your class D contains two A objects - the one inherited by B and the one inherited by C
When you call C::test() you change the A object in C.
When you call D::get() - which calls B::get() - you inspect the value of the A object in B.
One way to get around this is by means of virtual inheritance. That is not something you want to mess with until you understand how multiple inheritance works, though.
Can any one explain how delete x works correctly without virtual ~X()
#include <iostream>
struct B
{
B()
{
std::cout << "B()" << std::endl;
}
virtual ~B()
{
std::cout << "~B()" << std::endl;
}
};
struct C : B
{
C()
{
std::cout << "C()" << std::endl;
}
virtual ~C()
{
std::cout << "~C()" << std::endl;
}
};
template <class T>
struct X : T
{
X()
{
std::cout << "X()" << std::endl;
}
~X()
{
std::cout << "~X()" << std::endl;
}
};
template <class T>
struct Y : X<T>
{
Y()
{
std::cout << "Y()" << std::endl;
}
~Y()
{
std::cout << "~Y()" << std::endl;
}
};
int main()
{
std::cout << "====" << std::endl;
{
B* b = new C;
delete b;
}
std::cout << "====" << std::endl;
{
X<C>* x = new Y<C>;
delete x;
}
std::cout << "====" << std::endl;
return 0;
}
Output:
====
B()
C()
~C()
~B()
====
B()
C()
X()
Y()
~Y()
~X()
~C()
~B()
====
It is virtual – X<C> inherits C, the root of the hierarchy is B, and the destructor is declared virtual in B.
The class templating is completely irrelevant; it works exactly as it would if you had
struct X : C
{
X() { std::cout << "X()" << std::endl; }
~X() { std::cout << "~X()" << std::endl; }
};
struct Y : X
{
Y() { std::cout << "Y()" << std::endl; }
~Y() { std::cout << "~Y()" << std::endl; }
};
and
X* x = new Y;
delete x;
I have problem with understanding order of execution in virtual void/polymorphism based program.
As far as I understand what happens in other outputs, I have no idea why those commands:
a->b();
d->b();
d->a();
((G*)d) -> a();
give following outputs:
Nieznany
Nieznany
Gniewosz
Could anyone please explain me why those 3 methods print results as above?
#include <iostream>
using namespace std;
class C { public:
C() {cout << "Buduje A";}
void a() {cout << "Nauczyciel" << endl;}
virtual ~C() {cout << "~D" << endl;}
virtual void b() {cout << "Nieznany" << endl; }; };
class G {
int e; public:
G() {cout << "Buduje G ";}
void a() {cout << "Gniewosz " << endl;}
~G() {cout << "~C " << endl; }
void b() {cout << "Draka" << endl;}; };
class A :public C {
int o;
int a;
public:
A() {cout << "Buduje C ";}
~A() {cout << "~F " << endl;} };
class D :public A {
float f; public:
D() {cout << "Buduje D";}
virtual void a() {cout << "Pośrednik" << endl;}
~D() {cout << "~E" << endl;} };
class B :public D {
short s;
int b; public:
B() {cout << "Buduje E ";}
~B() {cout << "~G" << endl;} };
class E :public B {
E() {cout << "Buduje B";}
~E() {cout << "~I" << endl;} };
class F :public G, public D { public:
F() {cout << "Buduje F ";}
void a() {cout << "Nieznany " << endl;}
void b() {}
~F() {cout << "~H" << endl;} };
void nic() {cout << endl;}
int main() {
C*a = new B();
nic();
a->b();
D*d = new F;
nic();
d->b();
d->a();
((G*)d) -> a();
delete d;
delete a;
return 0; }
Im kinda new to C++.
I have an assignment where I should implement c class' default ctor and cctor so that theyll print "c::ctor" and "c::cctor" respectively.
I have no idea of how to deal with this, help would be appreciated.
#include <iostream>
#include <string>
using namespace std;
class a {
public:
a(const char* sname)
: _sname(sname) {
cout << "a::ctor" << endl;
}
a(const a& s) { cout << "a::copy ctor" << endl; }
virtual ~a() { cout << "a::dtor " << endl; }
void f1() { cout << "a::f1()" << endl; f2(); }
virtual void f2() = 0;
private:
string _sname;
};
class b1 : virtual public a {
public:
b1(const char* saname, const char* ssname)
: _sname1(saname), a(ssname) {
}
b1(const b1& b1) : a(b1) { cout << "b1 :: copy ctor << endl"; }
~b1() { cout << "b1::dtor" << endl; }
virtual void f1() { cout << "b1::f1()" << endl; }
virtual void f2() { cout << "b1::f2()" << endl; }
virtual void f3() { cout << "b1::f3()" << endl; }
private:
string _sname1;
};
class b2 : virtual public a {
public:
b2(const char* saname, const char* ssname)
: _sname2(saname), a(ssname) {
cout << "b2::ctor" << endl;
}
b2(const b2& b2) : a(b2) { cout << "b2::copy ctor" << endl; }
~b2() { cout << "b2::dtor" << endl; }
virtual void f3() { f1(); cout << "b2::f3()" << endl; }
private:
string _sname2;
};
class c : public b1, public b2 {
public:
c();
c(const c& c);
~c() { cout << "c::dtor" << endl; }
virtual void f1() { a::f1(); cout << "c::f1()" << endl; }
void f3() { cout << "c::f3()" << endl; }
};
In case of virtual inheritance, things are more complicated for the constructors and destructors. The constructors and the destructors of the virtual base class a should also be called in the c class since the compiler cannot choose between b1 or b2 to build the (unique) a part in the c object. For the destructor, the compilers handles things to call the destructor of b1, the destructor of b2 and the destructor of a.
So you should implement
class c : public b1, public b2 {
public:
c() : b1("", ""), b2("", ""), a("") {}
c(const c& src) : b1(src), b2(src), a(src) {}
};
In general, you should try to avoid virtual inheritance when not necessary. But it is a good exercise to understand how it works.