Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法访问c+;中派生类的函数+;_C++_Oop_Inheritance - Fatal编程技术网

C++ 无法访问c+;中派生类的函数+;

C++ 无法访问c+;中派生类的函数+;,c++,oop,inheritance,C++,Oop,Inheritance,我试图从基类的对象访问派生类的方法。我有一个基类CBase,它是一个抽象类 现在有两个类Ctype1和Ctype2是从CBase派生的类 class CType1:public CBase{ public: void StartBackup() { printf("Type1:%s",path); } void afunc() { printf("CType1:afunc\n"); } void my

我试图从基类的对象访问派生类的方法。我有一个基类
CBase
,它是一个抽象类

现在有两个类Ctype1和Ctype2是从CBase派生的类

    class CType1:public CBase{
public:
    void StartBackup()
    {
        printf("Type1:%s",path);
    }
    void afunc()
    {
        printf("CType1:afunc\n");
    }
    void myfunc()
    {
        printf("myfunc\n");
    }
};

class CType2:public CBase{
public:
    void StartBackup()
    {
        printf("Type2:%s",path);
    }
    void afunc()
    {
        printf("type2:afunc\n");
    }
    void typefunc()
    {
        printf("typefunc\n");
    }
};
我有一个类CManager,它的成员是类CBase的对象

    class CManager{
private:
    CBase * obj;
public:
    CManager(){
        obj = NULL;
    }
    ~CManager(){
        if(obj)
            delete obj;
        obj = NULL;
    }
    void inittype(int type)
    {
        if(type == 1)
        {
            obj = new CType1();
            obj->myfunc();
        }
        else
        {
            obj = new CType2();
            obj->typefunc();
        }

    }
};
void inittype(int-type)
函数中,我将输入作为类型,并相应地初始化CBase对象

我面临的问题是,在创建对象之后,当我尝试访问
myfunc
typefunc
时,会出现编译错误。如何访问这些函数(我不想在基类中创建这些函数)

编辑:

我得到的错误是

  • 'myfunc':不是'CBase'的成员
  • 'typefunc':不是'CBase'的成员

  • 谢谢

    如果您只需要在创建时访问非派生函数类,那么这将起作用

    void inittype(int type)
    {
        if(type == 1)
        {         
            CType1* temp = new CType1();
            temp->myfunc();
            obj = temp;
        }
        else
        {
            CType2* temp = new CType2();
            temp ->typefunc();
            obj = temp;
        }
    }
    
    如果您需要在其他时间访问这些成员函数,则需要使用cast-例如

    CType2* child = dynamic_cast<CType2*>(obj);
    
    CType2*child=dynamic_cast(obj);
    
    如果您只需要在创建时访问非派生函数类,那么这将起作用

    void inittype(int type)
    {
        if(type == 1)
        {         
            CType1* temp = new CType1();
            temp->myfunc();
            obj = temp;
        }
        else
        {
            CType2* temp = new CType2();
            temp ->typefunc();
            obj = temp;
        }
    }
    
    如果您需要在其他时间访问这些成员函数,则需要使用cast-例如

    CType2* child = dynamic_cast<CType2*>(obj);
    
    CType2*child=dynamic_cast(obj);
    
    在基类中创建inittype虚函数(不执行任何操作),然后根据需要在派生类中重写它

    void CType1::inittype() {
        myfunc();
    }
    
    void CType2::inittype() {
        typefunc();
    }
    
    void CManager::inittype(int type)
    {
        if(type == 1)
        {
            obj = new CType1();
        }
        else
        {
            obj = new CType2();
        }
        obj->inittype();
    
    }
    

    在基类中创建inittype虚函数(不做任何操作),然后根据需要在派生类中重写它

    void CType1::inittype() {
        myfunc();
    }
    
    void CType2::inittype() {
        typefunc();
    }
    
    void CManager::inittype(int type)
    {
        if(type == 1)
        {
            obj = new CType1();
        }
        else
        {
            obj = new CType2();
        }
        obj->inittype();
    
    }
    

    我不清楚“我不想在基类中创建这些函数”是什么意思

    您似乎了解纯虚拟函数。如果在CBase中将问题函数声明为纯函数,则应该能够通过
    CBase*
    指针调用它们

    面向对象语言中一个可能的混淆是,“这是什么类型的”有两个答案,这取决于上下文。创建新对象时,类型就是确切的类型。当您通过引用或指针访问现有对象时,类型是一组可能的类型—基类和可能存在的所有子类。更准确地说,指针/引用的类型定义了可用于访问对象的接口。该接口必须在不引用派生类(编译基类时可能不存在派生类)的情况下已知,因此必须在基类(虚拟方法)中声明它

    如果要调用仅在派生类中已知的对象,有两个选项。一是首先不要忘记派生类。例如

    CType1 *temp = new CType1();
    obj = temp;
    
    temp->myfunc();
    
    另一种方法是确定在运行时使用的派生类,并使用转换来转换指针。(相对)安全的方法是使用
    dynamic\u cast

    CType1 *temp = dynamic_cast<CType1> (obj);
    
    if (temp)  {  temp->myfunc ();  }
    
    CType1*temp=dynamic_cast(obj);
    if(temp){temp->myfunc();}
    
    我还没有介绍如何在运行时识别类型。C++中有“运行时类型标识”(RTTI),但我很少使用它。在少数情况下,
    dynamic\u cast
    是正确的,我总是因为其他原因知道类型-或者对象位于一组封闭的类中,可以通过某些接口中的功能来识别,或者,只有一种可能发生在需要
    动态\u cast
    的代码中

    CType1 *temp = dynamic_cast<CType1> (obj);
    
    if (temp)  {  temp->myfunc ();  }
    

    这里的关键词是“封闭类集”-如果其他人继承了您的类,那么当代码访问您不知道的、因此无法识别的类型的对象时,您可能会遇到意外问题。这并不是OOP的真正问题,它是一个内置功能——您应该能够在OOP中扩展现有类,而无需通知编写基类的人,这就是继承的目的。虽然在语言中可以标记类
    final
    ,但如果您不想在这种情况下允许它,这可能是个好主意(IIRC C++11提供了一种方法,我只是不知道如何拼写它)。

    我不清楚您所说的“我不想在基类中创建这些函数”是什么意思

    您似乎了解纯虚拟函数。如果在CBase中将问题函数声明为纯函数,则应该能够通过
    CBase*
    指针调用它们

    面向对象语言中一个可能的混淆是,“这是什么类型的”有两个答案,这取决于上下文。创建新对象时,类型就是确切的类型。当您通过引用或指针访问现有对象时,类型是一组可能的类型—基类和可能存在的所有子类。更准确地说,指针/引用的类型定义了可用于访问对象的接口。该接口必须在不引用派生类(编译基类时可能不存在派生类)的情况下已知,因此必须在基类(虚拟方法)中声明它

    如果要调用仅在派生类中已知的对象,有两个选项。一是首先不要忘记派生类。例如

    CType1 *temp = new CType1();
    obj = temp;
    
    temp->myfunc();
    
    另一种方法是确定在运行时使用的派生类,并使用转换来转换指针。(相对)安全的方法是使用
    dynamic\u cast

    CType1 *temp = dynamic_cast<CType1> (obj);
    
    if (temp)  {  temp->myfunc ();  }
    
    CType1*temp=dynamic_cast(obj);
    if(temp){temp->myfunc();}
    
    我还没有介绍如何在运行时识别类型。C++中有“运行时类型标识”(RTTI),但我很少使用它。在少数情况下,
    dynamic\u cast
    是正确的,我总是因为一些其他原因知道类型-或者对象在一个封闭的集合中