Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用子类中的自定义虚函数初始化基成员变量_C++_Design Patterns - Fatal编程技术网

C++ 如何使用子类中的自定义虚函数初始化基成员变量

C++ 如何使用子类中的自定义虚函数初始化基成员变量,c++,design-patterns,C++,Design Patterns,StructComponent类的构造函数根据info的传入对象的类型,采用不同的逻辑初始化其成员变量。这里我使用casting将pass-in参数转换为right子类对象 class StructComponent { public: StructComponent(const ClassA& info) { if (info.getType() == CLASS_B) { const ClassC& cl

StructComponent类的构造函数根据info的传入对象的类型,采用不同的逻辑初始化其成员变量。这里我使用casting将pass-in参数转换为right子类对象

class StructComponent
{
public:
    StructComponent(const ClassA& info)
    {
        if (info.getType() == CLASS_B)
        {
            const ClassC& classC = dynamic_cast<const ClassC&> info;
            ...
            apply a different logic for ClassB and init member accordingly
        } else if (info.getType() == CLASS_C) {
            apply a different logic for others
            ...
        } else {
                    apply default
            }
    }
}

class ClassA
{
public:
    ClassA(...)
    {
        m_shp = CreateStructComponent();
    }   
    virtual boost::shared_ptr<StructComponent> CreateStructComponent()
    {
        return boost::shared_ptr<StructComponent> (new StructComponent(*this));     
    }

    ...
    int getType() const { return CLASS_A; }

protected:
    boost::shared_ptr<StructComponent> m_shp;
}

class ClassB : public ClassA
{
public:
    ...

    virtual boost::shared_ptr<StructComponent> CreateStructComponent()
    {
        return boost::shared_ptr<StructComponent> (new StructComponent(*this));     
    }   
    ...
    int getType() const { return CLASS_B; } 
}

class ClassC : public ClassA
{
public:
    ...

    virtual boost::shared_ptr<StructComponent> CreateStructComponent()
    {
        return boost::shared_ptr<StructComponent> (new StructComponent(*this));     
    }   
    ...
    int getType() const { return CLASS_C; } 
}
类结构组件
{
公众:
结构组件(const ClassA和info)
{
if(info.getType()==CLASS_B)
{
const ClassC&ClassC=动态演员信息;
...
相应地为ClassB和init成员应用不同的逻辑
}else if(info.getType()==CLASS_C){
为其他人应用不同的逻辑
...
}否则{
应用默认值
}
}
}
甲级
{
公众:
A类(…)
{
m_shp=CreateStructComponent();
}   
虚拟boost::shared_ptr CreateStructComponent()
{
返回boost::shared_ptr(新结构组件(*this));
}
...
int getType()常量{return CLASS_A;}
受保护的:
boost::共享_ptr m_shp;
}
B类:公共A类
{
公众:
...
虚拟boost::shared_ptr CreateStructComponent()
{
返回boost::shared_ptr(新结构组件(*this));
}   
...
int getType()常量{return CLASS_B;}
}
C类:公共A类
{
公众:
...
虚拟boost::shared_ptr CreateStructComponent()
{
返回boost::shared_ptr(新结构组件(*this));
}   
...
int getType()常量{return CLASS_C;}
}
Q1>忽略潜在设计问题的代码是否正确

Q2>假设ClassA的所有子类都具有函数CreateStructComponent的相同实现体。 有没有一种方法可以节省空间,不重复执行以下相同的代码:

return boost::shared_ptr<StructComponent> (new StructComponent(*this));
returnboost::shared_ptr(新结构组件(*this));
Q3>我可以使用更好的设计吗?例如,有没有一种方法可以让我忽略
结构组件

在执行类
A
的构造函数期间,对象的类型为
A
。因此,将始终调用基本实现。因此,您可以省去重新键入实现的麻烦

此代码设计不正确;错误设计的代码永远都是不正确的,至少在“正确”这个词的通常意义上是如此


没有理由,如果C++规则对你不适用,为什么你应该使用构造函数来初始化。只需将其设置为一个方法,调用thing
Initialize
,您就可以从
Initialize
调用所需的任何虚拟方法,产生您似乎期望的效果。

在执行类
a
的构造函数期间,对象的类型是
a
。因此,将始终调用基本实现。因此,您可以省去重新键入实现的麻烦

此代码设计不正确;错误设计的代码永远都是不正确的,至少在“正确”这个词的通常意义上是如此

没有理由,如果C++规则对你不适用,为什么你应该使用构造函数来初始化。只要把它变成一个方法,调用东西
Initialize
,你就可以从
Initialize
中调用你想要的任何虚拟方法,产生你似乎期望的效果。

1)不,这不正确,至少它没有达到你可能期望的效果。它在
ClassA
的构造函数中调用一个虚拟函数,它总是调用
ClassA::CreateStructComponent()
而不是调用派生类中的重写函数,因为当
ClassA
构造函数运行时,动态类型是
ClassA
。出于同样的原因,在
StructComponent
的构造函数中,
getType()
调用将始终解析为
ClassA::getType()

2) 有很多方法可以解决这个问题。您可以将代码放在模板中,因此它取决于类型,或者您也可以通过在不同的位置执行初始化来消除复制代码的需要

3) 为什么不简单地给
StructComponent
重载构造函数,一个取
ClassB
,一个取
ClassC
,另一个取
ClassA

同样,一个更好的解决方案可能是去掉
StructComponent
构造函数,让
ClassA
ClassB
、或
ClassC
显式地进行初始化,以便每种类型都按照自己的方式进行初始化。如果初始化取决于创建它的类型,则初始化不属于
StructComponent
构造函数。目前,您有一个循环依赖项,
StructComponent
需要了解使用它的所有类型,而使用它的所有类型都需要了解
StructComponent
。这通常是设计问题的一个标志,所有的类都是紧密耦合的。如果
StrictComponent
对其他类型一无所知,那就更好了

无论如何,这里有一个可能的解决方案,展示了一种在不复制代码的情况下将正确类型传递给
StructComponent
的方法,但我认为这不是一个好的设计。请注意,
Structcomponent
构造函数被传递为NULL,因此它可以根据类型执行不同的操作,但是无法访问它传递的对象

class StructComponent
{
public:
    explicit StructComponent(const ClassA*)
    { /* something */ }

    explicit StructComponent(const ClassB*)
    { /* something else */ }

    explicit StructComponent(const ClassC*)
    { /* something completely different */ }
};

class Base
{
protected:
  template<typename T>
    explicit
    Base(const T*)
    : m_shp( boost::make_shared<StructComponent>((T*)NULL) )
    { }

    boost::shared_ptr<StructComponent> m_shp;
};

class ClassA : virtual public Base
{
public:
    ClassA() : Base(this) { }
};

class ClassB : public ClassA
{
public:
    ClassB() : Base(this) { }
};

class ClassC : public ClassA
{
public:
    ClassC() : Base(this) { }
};
这里还有另一个选择,这次没有循环依赖,将不同的初始化代码移到它所属的位置:

struct StructComponent
{
  StructComponent() { /* minimum init */ }
};

class ClassA
{
public:
    ClassA() : m_shp( createA() ) { }

protected:
    struct no_init { };

    explicit
    ClassA(no_init)
    : m_shp()
    { }

    boost::shared_ptr<StructComponent> createA()
    {
      // something
    }

    boost::shared_ptr<StructComponent> m_shp;
};

class ClassB : public ClassA
{
public:
    ClassB()
    : ClassA(no_init())
    { m_shp = createB(); }

private:
    boost::shared_ptr<StructComponent> createB()
    {
      // something else
    }
};

class ClassC : public ClassA
{
public:
    ClassC()
    : ClassA(no_init())
    { m_shp = createC(); }

private:
    boost::shared_ptr<StructComponent> createC()
    {
      // something completely different
    }
};
struct结构组件
{
StructComponent(){/*最小初始值*/}
};
甲级
{
公众:
ClassA():m_shp(createA()){}
受保护的:
结构no_init{};
明确的
A类(无初始)
:m_shp()
{ }
boost::shared_ptr createA()
{
//某物
struct StructComponent
{
  StructComponent() { /* minimum init */ }
};

class ClassA
{
public:
    ClassA() : m_shp( createA() ) { }

protected:
    struct no_init { };

    explicit
    ClassA(no_init)
    : m_shp()
    { }

    boost::shared_ptr<StructComponent> createA()
    {
      // something
    }

    boost::shared_ptr<StructComponent> m_shp;
};

class ClassB : public ClassA
{
public:
    ClassB()
    : ClassA(no_init())
    { m_shp = createB(); }

private:
    boost::shared_ptr<StructComponent> createB()
    {
      // something else
    }
};

class ClassC : public ClassA
{
public:
    ClassC()
    : ClassA(no_init())
    { m_shp = createC(); }

private:
    boost::shared_ptr<StructComponent> createC()
    {
      // something completely different
    }
};