【发布时间】:2014-10-13 21:21:13
【问题描述】:
我有:
class A {
virtual void foo() = 0;
virtual void bar() = 0;
};
class Fooing {
virtual void foo() = 0;
};
class Barring {
virtual void bar() = 0;
};
class TallFooing : public Fooing {
void foo(){ std::cout << "tall foo" << std::endl; }
};
class ShortFooing : public Fooing {
void foo(){ std::cout << "short foo" << std::endl; }
};
class BlueBarring : public Barring {
void bar() { std::cout << "blue bar" << std::endl; }
};
class RedBarring : public Barring {
void bar() { std::cout << "red bar" << std::endl; }
};
template <typename S, typename T>
class B : public A, public S, public T { };
int main() {
A* a1 = new B<TallFooing, RedBarring>();
A* a2 = new B<ShortFooing, BlueBarring>();
a1->foo(); a1->bar();
a1->foo(); a2->bar();
};
在 Barring 课程中混音是“好主意”(TM)吗?我做对了吗?如果没有,您能否提出替代方案/改进措施?
还有,下面的呢:
class Fooing {
virtual void foo() = 0;
};
class Barring {
virtual void bar() = 0;
};
class A : public virtual Fooing, public virtual Barring { };
class TallFooing : public Fooing {
void foo(){ std::cout << "tall foo" << std::endl; }
};
class ShortFooing : public Fooing {
void foo(){ std::cout << "short foo" << std::endl; }
};
class BlueBarring : public Barring {
void bar() { std::cout << "blue bar" << std::endl; }
};
class RedBarring : public Barring {
void bar() { std::cout << "red bar" << std::endl; }
};
template <typename S, typename T>
class B : public virtual A, public S, public T { };
和同样的main()?
注意事项:
-
foo()和bar()确实是独立的,任何组合都可以。也就是说,什么都不会损坏。
【问题讨论】:
-
如果 A 实现了
bar(),编译器会将a1->bar()之类的调用视为模棱两可,因为您真的要调用谁的bar()?这就是钻石问题,您可以使用像您这样的方法来跳线。 -
@AndyG:注意我的编辑。
-
我的评论仍然有效。另外,我认为您在
TallFooing和ShortFooing中有错字(应该分别是TallFoo和ShortFoo) -
那些告诉你不要对这样的接口使用多重继承,然后告诉你在Java中使用接口的人,可以放心地忽略。另外,我没有在你的遗产中看到任何钻石。但是,我确实看到了一个类 B,它继承了两个名为 foo() 的函数(一个来自 A,一个来自 S),这令人困惑,甚至可能无法编译。你应该避免混淆!
-
编写无法编译的代码不是一个好主意。请提出可以做的事情,然后问是否应该做。
标签: c++ multiple-inheritance virtual-inheritance idioms