Creating an instance of a derived class using an instance of the base class

I have an instance of a base class, there is a derived class that inherits from the base class, I want to convert the base instance to a derived instance (if possible without copying anything (maybe by sending a link to the base class to the derived class)) How can I achieve this ?

Note. I need this because I use a factory design template that identifies the derived class that needs to be created using a parameter located in the base instance.

//class A
//class B: public A (pure virtual)
//class C: public B

B BFactory::makeB(A &a) {
    int n=a.getN();
    if(n==1){
        return new C();
    }
}

Thank.

+4
source share
2 answers

Consider the case of a car.

You can treat Lamborghini like a car.

You can interpret Yugo as a car.

Lamborghini, Lamborghini. ++ , Lamborghini. Lamborghini , dynamic_cast. Lamborghini, dynamic_cast NULL. Yugo Lamborghini Yugo.

Lamborghini , . Lamborghini , Lamborghini-ness. .

!

, , :

//class A
//class B: public A (pure virtual)
//class C: public B

B BFactory::makeB(A &a) {
    int n=a.getN();
    if(n==1){
        return new C();
    }
}

C B B. B , C, . B , . , new C()

, ,

B * BFactory::makeB(A &a) {
    int n=a.getN();
    if(n==1){
        return new C();
    }
}

: make B , A , B.

class B: public A
{
public:
    virtual ~B(){}
    static B * makeB(A & a)
    {
        switch(a.getN())
        {
            case 1:
                return new C();
        }
        return NULL;
    }
};

: B -? A ? A ? . - , . .

class B: public A
{
public:
    virtual ~B(){}
    virtual B* makeB() = 0;
};

B Bs, A, , B, , , - , , - . , - , B .

class C: public B
{
public:
    B* makeB()
    {
        return new C();
    }
};

class D: public B
{
public:
    B* makeB()
    {
        return new D();
    }
};

: factory

factory. . . , , A. factory , . A, , A factory, A.

BFactory.h:

#ifndef BFACTORY_H_
#define BFACTORY_H_

#include <exception>
class B
{
public:
    virtual ~B(){}
    virtual std::string whatAmI() = 0;
protected:
    // data members common to all B subclasses
};

enum bType
{
    gimmie_a_C,
    gimmie_a_D,
    gimmie_an_E
};

class BadTypeException: public std::exception
{
public:
    const char* what() const noexcept
    {
        return "Dude! WTF?!?";
    }
};

B* BFactory(enum bType type);

#endif /* BFACTORY_H_ */

. , , , . : gimme_a_C, 1, , , .

enum bType
{
    gimmie_a_C,
    gimmie_a_D,
    gimmie_an_E
};

, (gimmie_an_E), factory - .

class BadTypeException: public std::exception
{
public:
    const char* what() const noexcept
    {
        return "Dude! WTF?!?";
    }
};

, factory. C. D. , C D , , enum bType. , - , - B.

BFactory.cpp:

#include "BFactory.h"

class C:public B
{
    std::string whatAmI()
    {
        return "C";
    }
};

class D:public B
{
    std::string whatAmI()
    {
        return "D";
    }
};

B* BFactory(enum bType type)
{
    switch(type)
    {
        case gimmie_a_C:
            return new C();
        case gimmie_a_D:
            return new C();
        default:
            throw BadTypeException();
    }
}

, , .

, main.cpp:

#include "BFactory.h"

int main()
{
    B * temp;
    temp = BFactory(gimmie_a_C);
    std::cout << temp->whatAmI() << std::endl;
    delete temp;
    temp = BFactory(gimmie_a_D);
    std::cout << temp->whatAmI() << std::endl;
    delete temp;
    //temp = BFactory(1001); // won't compile
    try
    {
        temp = BFactory(gimmie_an_E); // will compile, throws exception 
        std::cout << temp->whatAmI() << std::endl;
    }
    catch(BadTypeException& wtf)
    {
        std::cerr << wtf.what() << std::endl;
    }
}

- A A., , B B.

, , . unique_ptr B .

std::unique_ptr<B> BFactory(enum bType type)
{
    switch(type)
    {
        case gimmie_a_C:
            return std::unique_ptr<B>(new C());
        case gimmie_a_D:
            return std::unique_ptr<B>(new D());
        default:
            throw BadTypeException();
    }
}

main:

int main()
{
    std::unique_ptr<B> temp;
    temp = BFactory(gimmie_a_C);
    std::cout << temp->whatAmI() << std::endl;
    temp = BFactory(gimmie_a_D);
    std::cout << temp->whatAmI() << std::endl;
}
+4

, :

        #include <memory>
        #include <iostream>

        class Base
        {
        protected:

            struct CommonData
            {
                int A;
                int B;
            };

            std::shared_ptr<CommonData> m_data;



        public:

            Base() : m_data(std::make_shared<CommonData>())
            {
                m_data->A = 0;
                m_data->B = 0;
            }

            void SetData(Base * source)
            {
                m_data = source->m_data;
            }


            int A() const { return m_data->A; }
            int B() const { return m_data->B; }

            void SetA(int value) { m_data->A = value; }
            void SetB(int value) { m_data->B = value; }
        };

        class Derived : public Base
        {
        public:
            int C;
        };

        using namespace std;

        int _tmain(int argc, _TCHAR* argv[])
        {

            Base base;
            base.SetA(12);
            base.SetB(46);

            Derived derived;
            derived.SetData(&base);
            derived.C = 555;

            cout << derived.A() << endl; // 12         
            cout << derived.C << endl; // 555;

            cin.get();
        }
0

All Articles