Cast (or copy) Base class into sub class

Oct 21, 2019 at 4:40am
Dear experts

I understand the mechanism of downcast, that is, base class can be cast into the sub class when the sub class object is instantiated in the base class pointer.

However, sometimes, it is needed that initially base class is constructed (and generate some member variables common to the sub classes), and needed to be cast (or copied) to the sub class. Of course, such a cast is usually prohibited in the way of downcast (dynamic_cast etc).
Is there a way to treat such a case in the scheme of C++ language specification?

(I come up with the idea to handle such a situation as virtual function to copy base class in the sub classes as the below. But, I feel this is bothersome when the base class has a lot of member variables, which needs many copy (substitution) statements. Is there a smart way?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base{
protected:
  int _dummy_base;
public:
  virtual Base* copyFromBase(Base* obj) {return new Base(*obj);};
};

class SubClass : public Base{
protected:
  int _dummy_sub;
public:
  virtual Base* copyFromBase(Base* obj) {
    SubClass* ret = new SubClass();
    ret->_dummy_sub = 0;
    ret->_dummy_sub = obj->_dummy_base;
    return ret;
  }
};



)



Kind regards
Last edited on Oct 21, 2019 at 5:57am
Oct 21, 2019 at 4:05pm
> it is needed that initially base class is constructed
> and needed to be cast (or copied) to the sub class.
then you surely have a constructor like this
1
2
3
4
SubClass::SubClass(const Base &b): 
   Base(b)
   //¿how to initialise subclass members?
{}
or you may call the assignment operator
1
2
3
SubClass* ret = new SubClass();
this->Base::operator=(*obj);
//¿what about subclass members? 
now, ¿what values will have the subclass member variables?
this smell of bad design
Last edited on Oct 21, 2019 at 4:05pm
Oct 21, 2019 at 6:17pm
Why is dummy_sub a copy of dummy_base? Why not have SubClass access dummy_base directly?
Oct 21, 2019 at 6:40pm
What you mean is that if you create a ‘Base’ pointer like so:
Base * p_to_base { new Derived };
then it will invoke the wrong overridden methods?

As far as I know, a derived class contains all the base class properties… Doesn’t it?
Can’t you access them because they are private?

It would be simpler if you posted an example of what you’re trying to achieve - maybe there are known workarounds.

Oct 21, 2019 at 7:41pm
>this smell of bad design
I remembe it was written that such a procedure was bad design in a book (effective c++?)

My code's intention is
(1) generate Base class object in a lot of different manner which contains many common member variables to derives.
(2) Then, cast the into derives, and set individual member variables for derives



Oct 21, 2019 at 7:46pm
>As far as I know, a derived class contains all the base class properties… Doesn’t it?
>Can’t you access them because they are private?

All public. But, constructor of Base class is designed to set all properties as arguments. Thus, before (1), I cannot construct derives and pass it to the generation step(1).
Last edited on Oct 21, 2019 at 7:49pm
Oct 21, 2019 at 7:48pm
1
2
3
4
SubClass::SubClass(const Base &b): 
   Base(b)
   //¿how to initialise subclass members?
{}


Is this copy constructor permitted?
member variables of subclass is just public member and no pointer, simple initialization.
I feel this statement works well.
Last edited on Oct 21, 2019 at 7:53pm
Oct 21, 2019 at 8:15pm
> My code's intention is
> (1) generate Base class object in a lot of different manner which contains
> many common member variables to derives.
> (2) Then, cast the into derives, and set individual member variables for derives
not sure if follow
you have one object of class base, then you want to operate on that object in different ways with objects of derived classes
sounds like `strategy' or `decorator' pattern

¿why all these object of derived classes have the same state?
perhaps you may simply point to that other object
¿is really inheritance the relationship between the classes?

nolyc wrote:
You're trying to do X, and you thought of solution Y. So you're asking about solution Y, without even mentioning X. The problem is, there might be a better solution, but we can't know that unless you describe what X is.



> SubClass::SubClass(const Base &b)
be careful
1
2
3
Base obj;
Subclass1 a(obj); //this works
Subclass2 b(a); //this also "works" 
Oct 21, 2019 at 8:29pm
Is this copy constructor permitted?

Do you mean the call to copy constructor of Base? Yes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Bar {
  Bar( const Bar & ); // copy constructor
};

struct Derived : Bar {
  Derived( const Bar & b ) // not a copy constructor
  : Bar( b ), // initialize base class with data. Legal
    x( 42 )   // initialize member with data
  {}

  Derived( const Derived & rhs ) // copy constructor
  : Bar( rhs ), // initialize base class with data. Legal
    x( rhs.x )  // initialize member with data
  {}

private:
  int x;
};

struct Foo {
  Foo( const Bar & b )
  : gaz( b ) // initialize member with data. Legal
  {}
private:
  Bar gaz;
};

Oct 21, 2019 at 8:43pm
Thank you so much, my problem might be solved.

>¿why all these object of derived classes have the same state?
>perhaps you may simply point to that other object
>¿is really inheritance the relationship between the classes?

Is it anti-pattern to have the same state in all inheritance family?
Common state is in Base class.
Oct 21, 2019 at 8:53pm
What about inheriting constructors?
https://en.cppreference.com/w/cpp/language/using_declaration

Dumb example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>

class Base {
public:
    int myprop_1;
    double myprop_2;

    Base(int myprop_1_arg, double myprop_2_arg);
    virtual int getMyprop() const;
};


Base::Base(int myprop_1_arg, double myprop_2_arg)
    : myprop_1 { myprop_1_arg }
    , myprop_2 { myprop_2_arg }
{
}


int Base::getMyprop() const
{
    return myprop_1;
}



class Derived : public Base {
public:
    using Base::Base;
    int getMyprop() const override;
    double getOtherprop() const;

private:
    double otherprop { 13.666 };
};


int Derived::getMyprop() const
{
    return myprop_1 + 1;
}


double Derived::getOtherprop() const
{
    return otherprop;
}


int main()
{
    Base * myptobase { new Derived(13, 66.6) };
    Derived * myptoderived { dynamic_cast<Derived*>(myptobase) };

    std::cout << myptobase->getMyprop() << ' '
              << myptobase->myprop_2 << '\n';
    std::cout << myptoderived->getMyprop() << ' '
              << myptoderived->myprop_2 << ' '
              << myptoderived->getOtherprop() << '\n';
}

Oct 21, 2019 at 11:02pm
Thank you, I would like to consider such a way.

BTW, this problem necessarily rooted in the design of generation of objects.
I know there are some design patterns (Abstract Factory, Builder etc).
But, I could not grasp their usefulness for my poor experience.

If you are familiar with the case of their best practices,
could you tell me?
Oct 22, 2019 at 2:26pm
Is it anti-pattern to have the same state in all inheritance family?
Common state is in Base class.
If you have the "same state in all [inherited classes]" then that state is common state and belongs in the base class:

Bad:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class B {
public:
    int i;
};

class D1 : public B {
public:
   string name;
    ...
};
class D2 : public B {
public:
   string name;
    ...
};


Better:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class B {
public:
    int i;
    string name;
};

class D1 : public B {
public:
    ...
};
class D2 : public B {
public:
   ...
};


Oct 24, 2019 at 3:00am
Thank you, everyone.
I could understand how to proceed.

I appreciate every kind helping.
Topic archived. No new replies allowed.