【问题标题】:C++ Multiple inheritance and templatesC++ 多重继承和模板
【发布时间】:2011-08-04 15:17:52
【问题描述】:

众所周知,C++ 允许多重继承。

上下文

我正在实现一个处理网络,其中一些处理节点相互连接,以使用一种修改后的观察者模式交换不同的数据。

可以发送某种类型数据的节点是“DataSender”,然后扩展这个抽象类。

可以接收某种类型数据的节点是“DataReceiver”,然后扩展这个抽象类。

这是我的一段代码:

DataReceiver.h

template <typename TReceivedData>
class DataReceiver {
        public:
            void receiveData(TReceivedData* receivedData)
            {
                m_receivedData = receivedData;
            }
            TReceivedData* getReceivedData()
            {
                return(m_receivedData);
            }
        private:
            TReceivedData* m_receivedData;

DataSender.h

template <typename TSentData>
class DataSender {
            public:
                void sendData(TSentData* sentData) 
                {
                    set<DataReceiver<TSentData>*>::const_iterator it;
                    for(it = m_receiverList.begin(); it != m_receiverList.end(); ++it)
                        (*it)->receiveData(sentData);
                }

                void addDataReceiver(DataReceiver<TSentData>* dataReceiver) 
                {
                    m_receiverList.insert(dataReceiver);
                }

                void removeDataReceiver(DataReceiver<TSentData>* dataReceiver) 
                {
                    m_receiverList.erase(dataReceiver);
                }

            private:
                set<DataReceiver<TSentData>*> m_receiverList;
        };

然后通过扩展这些抽象类中的一个或两个来简单地实现一个新节点。

问题

我想要一个发送“图像”和“文本”类型数据的节点:然后我有一个节点: 与:

class Node : public DataSender<Image>, DataSender<Text>

好吧,我想你已经看到了我的问题,编译不会允许这样做,因为如果我启动就会有歧义:

Node* node;
node->sendData(<my argument>);

因为它无法区分应该使用哪个 sendData() 和父类(来自继承)(这是多重继承的常见问题)。

  • 1) 有没有办法使用 sendData() 来解决歧义(我不确定有没有?

  • 2) 还有其他方法可以解决我的沟通问题吗? (我绝对希望有机会希望创建一个发送/接收数据的节点的最终用户可以通过扩展接口之类的东西轻松地做到这一点,并且数据应该位于不同的“通道”上:例如一个节点可以能够处理文本和图像,但只会发送图像...

感谢您的帮助,

朱利安,

【问题讨论】:

    标签: c++ templates inheritance image-processing multiple-inheritance


    【解决方案1】:

    它不漂亮,但你可以知道你打算调用哪个基类的函数

    node->DataSender<Text>::sendData(<my argument>);
    

    【讨论】:

      【解决方案2】:

      我认为您没有歧义问题,因为两个 sendData 成员函数采用不同的参数。问题更可能是由于在确定调用哪个函数时 C++ 按特定顺序检查基类,但在第一个具有正确 name 成员函数的函数中停止。然后,如果它找到了一个可以接受你提供的参数的参数,它就会调用它,否则它会发出你可能看到的错误。

      解决这个问题的方法是将以下几行添加到Node 类定义中:

      using DataSender<Image>::sendData;
      using DataSender<Text>::sendData;
      

      【讨论】:

      • 实际上,它会首先确定在哪个类上解析函数,然后才解析重载。这两个函数在它们一起出现在一个类中之前不是重载 - 并且在您添加该 using 语句之前,它们不会。它们都是基类转换,并且由于编译器不能更喜欢它们,所以它只是声称它是模棱两可的。
      • 如果DataSender中会有一个方法只返回不同类型的结果,不接受任何参数。如何避免模棱两可的调用?
      • 完全如 Bo Persson 的回答中所述。
      • @Nicola - 我认为这是一个比我更好的答案,但显然不是每个人都同意。
      • 先生。 downvoter,您愿意解释一下您认为我的回答有什么问题吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多