Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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++_Class_Polymorphism - Fatal编程技术网

C++ 流式运算符和多态基类列表

C++ 流式运算符和多态基类列表,c++,class,polymorphism,C++,Class,Polymorphism,我有一个类向量,我想在屏幕上显示它们各自的参数。每个类都继承自CBase,向量只是CBase类型的指针列表 我希望避免将显示代码耦合到类。因此,我将流操作符放在类定义之外 所以我的类被定义为 class CBase { public: virtual ~CBase(){} }; class CChildA : public CBase { }; class CChildB : public CBase { }; 向量的设置如下: void main() { CChil

我有一个类向量,我想在屏幕上显示它们各自的参数。每个类都继承自
CBase
,向量只是
CBase
类型的指针列表

我希望避免将显示代码耦合到类。因此,我将流操作符放在类定义之外

所以我的类被定义为

class CBase 
{
public:
    virtual ~CBase(){}
};

class CChildA : public CBase
{
};

class CChildB : public CBase
{
};
向量的设置如下:

 void main()
{

    CChildA A;
    CChildB B;

    std::vector<CBase*> myList;
    myList.push_back(&A);
    myList.push_back(&B);

    display(myList);
}

但有人告诉我,人们不赞成使用
dynamic\u cast
。有没有一种简单的方法可以在没有动态播放的情况下实现这一点呢?

在这一点上,我不得不问你

您的所有派生类都应该实现流操作吗?

如果答案是‘是’或‘当然!’,那你为什么不把它作为你的界面的一部分呢

是的,您将看到这样一个事实:您现在支持将对象打印到流。但是,您自己也说过,它是所有派生类都必须具有的属性

让我们考虑另一个问题-

如果我应该添加一个新的派生类,那么代码中的其他位置是否应该更改?

嗯。。。当然可以,但这些应该是小的变化。你不想改变每一个使用流媒体运营商的地方。那将违反法律


关于此——

我希望避免将显示代码耦合到类。因此,我将流操作符放在类定义之外

你可以:

  • 错误地认为显示器应该与基座分离
  • 有人违规
  • 如果每个派生类都应该是可显示的,并且包含数据的容器应该显示每个元素,那么只需将相关方法添加到基类中即可

    如果大部分代码与显示代码无关,而这些类实际上与显示机制无关,那么每个派生类可能都应该继承两个接口(纯抽象类)

  • Base
  • IDisplayable
    (根据需要命名)
  • 并且您正在显示的显示方法应该接收
    向量
    ,而不是
    向量

    注意

    如果您被迫采用
    向量
    ,则应迭代元素并将其转换为
    IDisplayable*
    静态转换
    动态转换
    ,这实际上取决于您的情况)

    这与当前的解决方案不同,因为您只需要一个强制转换(而不是为每个派生类进行强制转换)

    注2


    我不太喜欢重载“”运算符。我将在接口中考虑一个纯虚拟函数,称为“显示”,而不是虚拟运算符。
    std::ostream & operator<<(std::ostream & os, const CChildA & item)
    {
        os << "Child A Values Here";
        return os;
    }
    
    std::ostream & operator<<(std::ostream & os, const CChildB & item)
    {
        os << "Child B Values Here";
        return os;
    }
    
    void display(std::vector<CBase*> &aList)
    {
        for(std::vector<CBase*>::iterator it = aList.begin(); it != aList.end(); it++)
        {
            if(CChildA * ca = dynamic_cast<CChildA*>(*it))
                std::cout << *ca << "\n";
            else if(CChildB * cb = dynamic_cast<CChildB*>(*it))
                std::cout << *cb << "\n"; 
        }
    }