-1

在 C++ 中实现这一点的更好方法是什么(没有 if-else)。在 CI 中可以初始化函数指针,然后调用函数指针。所以如果你看C类,C类的一些对象只使用A类和一些B类。我对C比C++更熟悉。

class A {
public:
   int func1();
   int func2();
   int func3();
};

class B:A {
public:
   int func1() {x=1; A::func1();}
   int func2()  {A::func2(); x=1;}
   int func3()  {x=1; A::func2();}
};

class C {
public:
    C::C(bool class_a) {_class_a = _class_a;}

    void func_c_1()
    {
        if(_class_a) a.func1();
        else b.func1();
    }
    void func_c_2()
    {
        if(_class_a) a.func2();
        else b.func2();
    }
    void func_c_3()
    {
        if(_class_a) a.func3();
        else b.func3();
    }
private:
    bool _class_a;
    A a;
    B b;
};
4

2 回答 2

4

您的代码无法编译,我可能会完全误解您,但是如果您想要一个根据创建方式执行不同操作的类,则可以通过使用具有纯虚函数的虚拟基并从中派生 A 和 B 来覆盖那些虚函数。

class Base
{
public:
    virtual int func1() = 0;
    virtual int func2() = 0;
    virtual int func3() = 0;
    virtual ~Base(){}         //it is important that this is virtual 
};

class A: public Base
{
    public:
    virtual int func1(){
        //do something
    }
    virtual int func2(){
        //do something
    }
    virtual int func3(){
        //do something
    }
};

class B: public A
{
    public:
    virtual int func1(){
        //do something else
        ((A*)this)->func1(); //call A's func1()
    }
    virtual int func2(){
        //do something else
    }
    virtual int func3(){
        //do something else
    }
};
Base *a = new A;
Base *b = new B;

Base *c = a;
c->func1();     //does something
c=b;
c->func1();     //does something else

否则,如果您本质上想要两个不同的类(具有不同的类型),您可以使用模板。如果这是您想要评论的内容,我将添加示例代码。

还应该注意的是,没有什么能阻止你在 C++ 中使用函数指针,尽管我不推荐它。这是一个仅用于咯咯笑的示例代码:

#include <functional>
class A
{
public:
    int func1(){
    //do something
        return 1;
    }
    int func2(){
    //do something
        return 1;
    }
    int func3(){
    //do something
        return 1;
    }
};

class B
{
public:
    int func1(){
    //do something else
        return 1;
    }
    int func2(){
    //do something else
        return 1;
    }
    int func3(){
    //do something else
        return 1;
    }
};

class C
{
public:
    C(bool useA)
    {
        if(useA)    {
            func1 = std::bind(&A::func1,a_);
            func2 = std::bind(&A::func2,a_);
            func3 = std::bind(&A::func3,a_);
        }
        else    {
            func1 = std::bind(&B::func1,b_);
            func2 = std::bind(&B::func2,b_);
            func3 = std::bind(&B::func3,b_);
        }
    }
    std::function<int()> func1;
    std::function<int()> func2;
    std::function<int()> func3;
private: 
    A a_;
    B b_;
};

C c(true);
C c2(false);
c.func1();
于 2013-02-08T18:38:19.297 回答
1

在我看来,您正在尝试理解 C++ 中的继承。您的代码看起来像是试图获得不同的行为,具体取决于您告诉它是 A 类还是 B 类。如果是这样,这应该会有所帮助:

#include <iostream>
using namespace std;

class A
{
    public:
        void foo() { cout << "A::foo\n"; }
        void bar() { cout << "A::bar\n"; } 
};

class B : public A
{
    public:
        void foo() { cout << "B::foo\n"; }
        void fee() { cout << "B::fee\n"; }
};

main()
{
    A* a = new A();
    B* b = new B();

    a->foo();
    a->bar();
    b->foo();
    b->bar();
    b->fee();
    ((a)b)->foo();
    ((a)b)->bar();
}

我创建了 A 类,并(公开)使 B 类继承自它。在 main 中,前 5 行显示了您期望的行为,但是如果您希望b对象充当A,我只需将其强制转换为它,它就可以了。(如果您运行此代码,您将看到最后foo一行发出 A::foo。)因此该行为在构造时不是强制的。当你构造对象时,B::foo 会覆盖 A::foo。但只需转换为超类,您就可以访问原始函数。

请注意,如果您想b.foo()始终发出“B::foo”,请将 A 中的 foo 函数设置为虚拟:

class A
{
    public:
        virtual void foo() { cout << "A::foo\n"; }
        void bar() { cout << "A::bar\n"; } 
        virtual ~foo() { /* any destructor code for the base class */ }
};

在这种情况下,无论您使用b->foo()((A*)b)->foo(),输出都是“B::foo”。运行时将使用对象的原始类型,而不是使用您将其转换为的类型。 重要- 一旦你在你的类中创建了任何虚拟函数,你必须为该函数创建一个虚拟析构函数。如果你不这样做,当你的对象被删除时,只会调用基类的析构函数。(当您使用虚拟析构函数时,每个析构函数都从派生最多的类调用到基类,本质上是在构造对象时展开的工作。)

希望这可以帮助...

于 2013-02-08T19:39:44.567 回答