【问题标题】:C++ multiple inheritance off identically named operatorC++ 对同名运算符的多重继承
【发布时间】:2010-12-31 16:34:10
【问题描述】:

是否可以从两个不同的抽象类继承同名运算符,但返回类型不同。 如果是这样,他们:

  • 实现运算符的语法是什么

  • 使用/解析运算符的语法是什么

  • 一般情况下的开销是多少,与任何其他虚函数相同?

如果您能提供有用的参考或示例代码

谢谢

12结构抽象矩阵{ 13 virtual double& operator()(int i, int j); 14}; 15 16 结构抽象块矩阵{ 17 virtual double* operator()(int i, int j); 18}; 19 20struct block_matrix:abstract_matrix,abstract_block_matrix { 21 22};

块矩阵需要为两个运算符提供实现,以便它是矩阵或块矩阵,具体取决于上下文。我不知道如何提供特定于 block_matrix 类的实现。 现在,它是通过将对象包装类型作为最后一个参数传递来完成的,但这似乎不是很干净。我想保留纯矩阵符号。

【问题讨论】:

  • “虚拟课程”是什么意思?你的意思是虚拟继承?您的意思的代码示例(即使它没有编译)会有所帮助。

标签: c++ inheritance virtual multiple-inheritance


【解决方案1】:

函数的返回类型不是它的签名的一部分,所以你不能在 block_matrix 中有两个 operator+(i,j) - 这将是一个模棱两可的调用。因此,在这一点上,多重继承有点像红鲱鱼。你不能那样做。

你真正想做什么,为什么?

无论如何,对于您的另一个问题:虚拟运算符在性能和操作方式方面与虚拟函数完全相同。您使用它们的方式只是在语义上略有不同 - 但在底层它们只是像其他任何函数一样。

【讨论】:

  • 我不这么认为。在一种情况下,您正在覆盖 abstract_matrix:: 运算符,在另一种情况下,您正在覆盖 abstract_block_matrix:: operator.so 原则上我认为有一种方法可以做到这一点。我有两种解决方法,但也有丑陋的。
  • 不,我说的是正确的。没有办法让一个类具有两个仅通过返回类型不同的相同函数。 “解决方法”是让它们的差异超过返回类型。
  • 看看这个。 A类有函数f,A::f。 B类也有函数f,B::f。现在 C 继承了 A 和 B。所以现在 C 可以访问 A::f 和 B::f。直接覆盖 A 或 B 的语法。因此,您可以访问两个 f,具体取决于 C 是 A 还是 B,但不能通过相同的对象转换访问两者。如果双亲都是抽象的,那么 C 可以通过中间的部分抽象类派生出来。
  • 是的。如果你在这种情况下调用 C::f,你会得到一个关于模棱两可调用的编译器错误。这就是我一直在说的。
  • 正确。是否可以跳过中间类并在一个地方同时定义 A::f 和 B::f?
【解决方案2】:

您不能重载返回类型。当调用函数或运算符时,编译器必须知道要调用哪一个。它不会根据分配给函数(运算符)调用的内容来推断。

看起来您正在寻求实现一些矩阵数学。也许如果您下载 DirectX SDK 或 OpenGL 并看看他们是如何做到的,您可能会得到一些关于如何正确做到这一点的想法。

【讨论】:

  • 我知道返回类型不可重载。然而,inheritance 似乎并非如此,无论如何编译器不会抱怨。我的矩阵要求不同,ublas 也不太适合
【解决方案3】:

我得到了它的工作,但它很不稳定。我确实喜欢模板。

template<class T>
class Base1
{
};

template<class T>
class Base2
{
};

class Derived;
template<>
class Base1<Derived>
{
public:
     double foo(){return 0.1;}
};

template<>
class Base2<Derived>
{
public:
    int foo(){return 1;}
};

class Derived
    : public Base1<Derived>
    , public Base2<Derived>
{
public:
    using Base1<Derived>::foo;
};

int main()
{
     double sum = 0;
     Derived d;
     sum += d.foo(); //+ .1
     Base1<Derived> * pI = &d;
     sum += pI->foo(); //+ .1

     Base2<Derived> * pF = &d;
     sum += pF->foo(); //+ 1

     return (sum*10);
}

没有模板我无法让它工作,尽管它看起来应该可以。我不确定你是否可以以同样的方式只做模板化的成员函数,但我的直觉说“不”。

就代码组织而言,我会在 Derived 的定义或声明之后立即定义 Base# 的内容,因为这正是它的用途。请记住,您可以使用typename Base1&lt;Derived&gt; something 让事情变得更漂亮。

编辑: 啊对!它不允许您使用“使用”技巧或具有不同的返回类型,但它更简单:

class Derived
    : public Base1
    , public Base2
{
    double Base1::foo(){...}
    double Base2::foo(){...}
}

可能有一种可怕的、可怕的、很棒的方式来结合这两种方法,但我认为在使用代码时它实际上并没有帮助。我可能会回复你。

【讨论】:

  • 我不明白你在做什么,但是不能使用限定名称来声明成员函数,如:double Base1::foo(){...}
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多