I have something like that (simplified)
我有类似的东西(简化)
class A
{
public:
virtual void Function () = 0;
};
class B
{
public:
virtual void Function () = 0;
};
class Impl : public A , public B
{
public:
????
};
How can I implement the Function () for A and the Function() for B ? Visual C++ lets you only define the specific function inline (i.e. not in the cpp file), but I suppose it's an extension. GCC complains about this. Is there a standard C++ way to tell the compiler which function I want to override?
如何为A实现Function()和为B实现Function()? Visual C ++允许您只定义内联的特定函数(即不在cpp文件中),但我认为它是一个扩展。海湾合作委员会抱怨这一点。是否有标准的C ++方式告诉编译器我要覆盖哪个函数?
(visual c++ 2008)
(visual c ++ 2008)
class Impl : public A , public B
{
public:
void A::Function () { cout << "A::Function" << endl; }
void B::Function () { cout << "B::Function" << endl; }
};
Thank you!
4 个解决方案
#1
31
You cannot use qualified names there. I you write void Function() { ... }
you are overriding both functions. Herb Sutter shows how it can be solved.
你不能在那里使用合格的名字。我写了void Function(){...}你正在覆盖这两个函数。 Herb Sutter展示了如何解决它。
Another option is to rename those functions, because apparently they do something different (otherwise i don't see the problem of overriding both with identical behavior).
另一个选择是重命名这些函数,因为显然它们做了不同的事情(否则我没有看到以相同的行为覆盖两者的问题)。
#2
2
As a workaround, try
作为一种解决方法,请尝试
struct Impl_A : A
{
void Function () { cout << "A::Function" << endl; }
};
struct Impl_B : B
{
void Function () { cout << "B::function" << endl; }
};
struct Impl : Impl_A, Impl_B {};
#3
1
I can suggest another way to resolve this issue. You can add wrapper Typed
which changes Function
signature by adding dummy parameter. Thus you can distinguish methods in your implementation.
我可以建议另一种方法来解决这个问题。您可以添加包装类型,通过添加虚拟参数来更改功能签名。因此,您可以区分实现中的方法。
class A {
public:
virtual void Function() = 0;
virtual ~A() = default;
};
class B {
public:
virtual void Function() = 0;
virtual ~B() = default;
};
template<typename T>
class Typed : public T {
public:
virtual void Function(T* dummy) = 0;
void Function() override {
Function(nullptr);
}
};
class Impl : public Typed<A>, public Typed<B> {
public:
void Function(A* dummy) override {
std::cerr << "implements A::Function()" << std::endl;
}
void Function(B* dummy) override {
std::cerr << "implements B::Function()" << std::endl;
}
};
The benefit of such solution is that all implementation are placed in one class.
这种解决方案的好处是所有实现都放在一个类中。
#4
-1
If A and B are interfaces, then I would use virtual derivation to "join" them (make them overlap). If you need different implementations for your Function
if called through a pointer to A
or to B
then I would strongly recommend to choose another design. That will hurt otherwise.
如果A和B是接口,那么我将使用虚拟推导来“连接”它们(使它们重叠)。如果通过指向A或B的指针调用函数需要不同的实现,那么我强烈建议您选择其他设计。否则会受到伤害。
Impl
"derives from" A
and B
means Impl
"is a" A
and B
. I suppose you do not mean it.
Impl“源自”A和B意味着Impl“是”A和B.我想你不是这个意思。
Impl
"implements interface" A
and B
means Impl
"behaves like" A
and B
. then same interface should mean the same behavior.
Impl“实现接口”A和B意味着Impl“表现得像”A和B.然后相同的接口应该表示相同的行为。
In both cases having a different behavior according to the type of pointer used would be "schizophrenic" and is for sure a situation to avoid.
在两种情况下,根据所使用的指针类型具有不同的行为将是“精神分裂症”并且肯定是要避免的情况。
#1
31
You cannot use qualified names there. I you write void Function() { ... }
you are overriding both functions. Herb Sutter shows how it can be solved.
你不能在那里使用合格的名字。我写了void Function(){...}你正在覆盖这两个函数。 Herb Sutter展示了如何解决它。
Another option is to rename those functions, because apparently they do something different (otherwise i don't see the problem of overriding both with identical behavior).
另一个选择是重命名这些函数,因为显然它们做了不同的事情(否则我没有看到以相同的行为覆盖两者的问题)。
#2
2
As a workaround, try
作为一种解决方法,请尝试
struct Impl_A : A
{
void Function () { cout << "A::Function" << endl; }
};
struct Impl_B : B
{
void Function () { cout << "B::function" << endl; }
};
struct Impl : Impl_A, Impl_B {};
#3
1
I can suggest another way to resolve this issue. You can add wrapper Typed
which changes Function
signature by adding dummy parameter. Thus you can distinguish methods in your implementation.
我可以建议另一种方法来解决这个问题。您可以添加包装类型,通过添加虚拟参数来更改功能签名。因此,您可以区分实现中的方法。
class A {
public:
virtual void Function() = 0;
virtual ~A() = default;
};
class B {
public:
virtual void Function() = 0;
virtual ~B() = default;
};
template<typename T>
class Typed : public T {
public:
virtual void Function(T* dummy) = 0;
void Function() override {
Function(nullptr);
}
};
class Impl : public Typed<A>, public Typed<B> {
public:
void Function(A* dummy) override {
std::cerr << "implements A::Function()" << std::endl;
}
void Function(B* dummy) override {
std::cerr << "implements B::Function()" << std::endl;
}
};
The benefit of such solution is that all implementation are placed in one class.
这种解决方案的好处是所有实现都放在一个类中。
#4
-1
If A and B are interfaces, then I would use virtual derivation to "join" them (make them overlap). If you need different implementations for your Function
if called through a pointer to A
or to B
then I would strongly recommend to choose another design. That will hurt otherwise.
如果A和B是接口,那么我将使用虚拟推导来“连接”它们(使它们重叠)。如果通过指向A或B的指针调用函数需要不同的实现,那么我强烈建议您选择其他设计。否则会受到伤害。
Impl
"derives from" A
and B
means Impl
"is a" A
and B
. I suppose you do not mean it.
Impl“源自”A和B意味着Impl“是”A和B.我想你不是这个意思。
Impl
"implements interface" A
and B
means Impl
"behaves like" A
and B
. then same interface should mean the same behavior.
Impl“实现接口”A和B意味着Impl“表现得像”A和B.然后相同的接口应该表示相同的行为。
In both cases having a different behavior according to the type of pointer used would be "schizophrenic" and is for sure a situation to avoid.
在两种情况下,根据所使用的指针类型具有不同的行为将是“精神分裂症”并且肯定是要避免的情况。