C++ 重载派生类中的虚拟方法,使其在C++;
我有一个抽象类C++ 重载派生类中的虚拟方法,使其在C++;,c++,inheritance,operator-overloading,abstract-class,C++,Inheritance,Operator Overloading,Abstract Class,我有一个抽象类A,使用纯虚方法voidfoo(inta)=0 然后我有几个类继承自A,它们都定义了方法foo。但是我需要其中一个参数,B,使它成为foo需要一个额外的参数,intb,所以有点过载 那么我想这样做: A *bInstance = new B(); bInstance -> foo(1, 2); 但是我得到一个错误,告诉我foo使用了太多的参数 写这篇文章时,我意识到这是一件很奇怪的事情,所以也许你不能做到这一点,你不能做到这一点很好。但是如果可能的话,请告诉我应该怎么做。只
A
,使用纯虚方法voidfoo(inta)=0
然后我有几个类继承自A
,它们都定义了方法foo
。但是我需要其中一个参数,B
,使它成为foo
需要一个额外的参数,intb
,所以有点过载
那么我想这样做:
A *bInstance = new B();
bInstance -> foo(1, 2);
但是我得到一个错误,告诉我foo
使用了太多的参数
写这篇文章时,我意识到这是一件很奇怪的事情,所以也许你不能做到这一点,你不能做到这一点很好。但是如果可能的话,请告诉我应该怎么做。只有当要使用的指针类型为B时,才可以使用B的重载函数 见:
#包括
#包括
甲级{
公众:
虚空foo(int a)=0;
};
B类:公共A
{
公众:
虚拟void foo(int a)覆盖
{
}
无效foo(内部a、内部b)
{
std::cout仅当要使用的指针类型为B时,才可以使用B的重载函数
见:
#包括
#包括
甲级{
公众:
虚空foo(int a)=0;
};
B类:公共A
{
公众:
虚拟void foo(int a)覆盖
{
}
无效foo(内部a、内部b)
{
虽然伯纳德的答案是有可能的,但你必须问问自己过载的影响是什么。例如,想想下面的例子
std::unique_ptr bAsA=std::make_unique();
bAsA->foo(1,2);//不工作。
bAsA->foo(1);//有效,但它应该做什么?
如果a
和B
之间有一个不同的接口,我建议以新基类的形式添加一个抽象层(我称之为C
)
所以不是
结构A{
//普通的
虚拟空栏(){}
//特定类别
虚空foo(int)=0;
};
结构B:公共A{
//奇怪的未使用的覆盖仍然可用
void foo(int)重写{}
//特定类别
void foo(int,int){}
};
使用
struct C{
//普通的
虚拟空栏(){}
};
结构A:public{
//特定类别
虚空foo(int)=0;
};
结构B:公共C{
//特定类别
void foo(int,int){}
};
尽管伯纳德的答案是有可能的,但你必须问问自己过载的影响是什么。例如,想想下面的例子
std::unique_ptr bAsA=std::make_unique();
bAsA->foo(1,2);//不工作。
bAsA->foo(1);//有效,但它应该做什么?
如果a
和B
之间有一个不同的接口,我建议以新基类的形式添加一个抽象层(我称之为C
)
所以不是
结构A{
//普通的
虚拟空栏(){}
//特定类别
虚空foo(int)=0;
};
结构B:公共A{
//奇怪的未使用的覆盖仍然可用
void foo(int)重写{}
//特定类别
void foo(int,int){}
};
使用
struct C{
//普通的
虚拟空栏(){}
};
结构A:public{
//特定类别
虚空foo(int)=0;
};
结构B:公共C{
//特定类别
void foo(int,int){}
};
您可以使用默认参数完全实现所需:
class A
{
public:
virtual void foo(int a, int b = 0) = 0;
virtual ~A() = default;
};
class B : public A
{
public:
void foo(int a, int b) override { }
};
class C : public A
{
public:
void foo(int a, int b = 0) override { }
};
int main()
{
A* b = new B();
A* c = new C();
b->foo(1, 2);
c->foo(1);
}
如果不需要,您不必在
C::foo
实现(以及任何其他派生类)中使用此参数。您可以使用默认参数完全实现所需的功能:
class A
{
public:
virtual void foo(int a, int b = 0) = 0;
virtual ~A() = default;
};
class B : public A
{
public:
void foo(int a, int b) override { }
};
class C : public A
{
public:
void foo(int a, int b = 0) override { }
};
int main()
{
A* b = new B();
A* c = new C();
b->foo(1, 2);
c->foo(1);
}
您不必在
C::foo
实现(以及任何其他派生类)中使用此参数如果不需要的话。为什么要这样做?我的意思是,如果派生类有另一个接口,为什么要使用公共基?这似乎是设计味道。为什么要这样做?我的意思是,如果派生类有另一个接口,为什么要使用公共基?这似乎是设计味道。我明白了,谢谢!这很有意义,当指针是编译器的类型a时转到类A中的foo声明,只看到1个参数耶,为了进一步继承,您应该添加一个虚拟析构函数。您可能应该使用std::make_unique或simple stack alloc。我更喜欢std::shared_ptr aPtr{b}
为了与您自己的建议保持一致和安全,提取原始指针不是很幸运(可能会试图删除它,从而导致SEGFULT)。我明白了,谢谢!这很有意义,当指针是A类型时,编译器会转到类A中的foo声明,只看到1个参数。是的,为了进一步的继承,您应该添加一个虚拟析构函数。并且您可能应该使用std::make_unique或simple stack alloc。我更喜欢std::shared_ptr aPtr{b}
为了与您自己的建议保持一致和安全,提取原始指针不是很幸运(可能会试图删除它,从而导致错误)。