0

这个标题已被多次使用,但在搜索了大约 5-6 个示例后,我找不到任何与我的问题相匹配的内容:

我有一个简单的继承实践。

A是一个基类,类BC继承自它:

class A {

};

class B : public A { public:    int i; };

class C : public A { public:    int j; };

还有一个类 P 包含这样的重载函数:

class P
{
public:
    void change(B *b)
    {
        b->i =1;
    }

    void change(C *c)
    {
        c->j =1;
    }
};

当我使用如下功能时:

int main()
{
    A *b = new B();
    A *c = new C();
    P p;
    p.change(b);
    p.change(c);
    return 0;
}

它给出了一个错误说:

inherit2.cpp: In function ‘int main()’:
inherit2.cpp:37:12: error: call of overloaded ‘change(A*&)’ is ambiguous
inherit2.cpp:37:12: note: candidates are:
inherit2.cpp:21:7: note: void P::change(B*) <near match>
inherit2.cpp:21:7: note:   no known conversion for argument 1 from ‘A*’ to ‘B*’
inherit2.cpp:26:7: note: void P::change(C*) <near match>
inherit2.cpp:26:7: note:   no known conversion for argument 1 from ‘A*’ to ‘C*’
inherit2.cpp:38:12: error: call of overloaded ‘change(A*&)’ is ambiguous
inherit2.cpp:38:12: note: candidates are:
inherit2.cpp:21:7: note: void P::change(B*) <near match>
inherit2.cpp:21:7: note:   no known conversion for argument 1 from ‘A*’ to ‘B*’
inherit2.cpp:26:7: note: void P::change(C*) <near match>
inherit2.cpp:26:7: note:   no known conversion for argument 1 from ‘A*’ to ‘C*’

如果您能帮我解决问题,我将不胜感激。拉赫曼

4

4 回答 4

2

你可以:

  • i通过为and添加虚拟 setter 函数来使用多态性j

    class A {
    public:
        virtual void set( int ) = 0;
    };
    
    class B : public A {
    public:
        void set( int value )
        {
            i = value;
        }
    
    private:
        int i;
    };
    
    class C : public A {
    public:
        void set( int value )
        {
            j = value;
        }
    
    private:
        int j;
    };
    
    class P
    {
    public:
        void change(A * obj)
        {
            obj->set(1);
        }
    };
    
    int main()
    {
        A *b = new B();
        A *c = new C();
        P p;
        p.change(b);
        p.change(c);
        return 0;
    }
    
  • 在传递指针之前对指针进行大小写:

     A *b = new B();
     A *c = new C();
     P p;
     p.change(static_cast<B*>(b));
     p.change(static_cast<C*>(c));
    
  • 将变量放入基类(并去掉两个change()函数):

    class A {
    public:
        int i;
    };
    
    class B : public A {};
    
    class C : public A {};
    
于 2012-10-12T10:47:17.593 回答
2
Polymorphism is one answer

class A
{
public:
    virtual void set() = 0;
};


class B : public A
{
public:
    virtual void set() { i = 1; }
private:
    int i;
};

class C : public A
{
public:
    virtual void set() { j = 1; }
private:
    int j;
};

class P
{
public:
    void change(A *a)
    {
        a->set();
    }
};

int main()
{
    A *b = new B();
    A *c = new C();
    P p;
    p.change(b);
    p.change(c);
    return 0;
}

有了多态性,就不需要多个change方法。

于 2012-10-12T10:51:25.860 回答
1

我会调整你的类层次结构以使用多态性:

class A
{
public:
    virtual void SetVariable(const int value) = 0;
};

class B : public A
{
public:
    virtual void SetVariable(const int value) override { i = value; }
    int i;
};

class C : public A
{
public:
    virtual void SetVariable(const int value) override { j = value; }
    int j;
};

class P
{
public:
    void change(A *a)
    {
        a->SetVariable(1);
    }
};

这样,您可以使用指向基类 ( A) 的指针,而无需知道它们是哪种特定的派生类型。

于 2012-10-12T10:50:44.723 回答
1

根本原因:

当你调用change()你传递的参数是类型A *时,类中的这个函数没有完全匹配P。编译器试图找到最佳匹配,它有两个选择:

void change(B *); 
void change(C *);

它们都不是最佳匹配,因为每个都需要从A*toB*或转换C*。并不是说您的类不提供此转换功能,因此编译器会报告错误。

解析度:

您可以通过使用强制转换来准确地告诉编译器要选择哪个版本的函数。

p.change(static_cast<B*>(b));  
p.change(static_cast<C*>(c)); 

在上述两种情况下,您都知道所指向对象的实际类型,A *因此您可以使用static_cast并指导编译器找到最佳匹配函数。

于 2012-10-12T10:52:16.437 回答