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}
为了与您自己的建议保持一致和安全,提取原始指针不是很幸运(可能会试图删除它,从而导致错误)。