一个班中的两个班

two classes within a class

本文关键字:两个 一个      更新时间:2023-10-16

在C++中实现这一点的更好方法是什么(没有if else)。在C中,我可以初始化函数指针,然后只调用函数指针。所以如果你看看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;
};

你的代码没有编译,我可能会完全误解你,但如果你想要一个根据创建方式做不同事情的类,你可以使用一个具有纯虚拟函数的虚拟库,并从中派生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();

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

#include <iostream>
using namespace std;
class A
{
    public:
        void foo() { cout << "A::foon"; }
        void bar() { cout << "A::barn"; } 
};
class B : public A
{
    public:
        void foo() { cout << "B::foon"; }
        void fee() { cout << "B::feen"; }
};
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函数设置为virtual:

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

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

希望这能帮助。。。

相关文章: