编译错误的原因是什么? [英] What is the reason for compilation error here?

查看:136
本文介绍了编译错误的原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请专家清除我的疑惑。

我不明白为什么它会抛出编译错误。这些是多态类,在主要的我分配的基指针与派生类指针,它应该找到func_2,因为__vptr的基数将指向派生类的__vtable。

或者我对__vtable和__vptr的理解存在一些差距。

请给我一些好的文章来清除我的疑问。

  class  base 
{
public
virtual int func_1()
{
cout<< 在func_1;
}
};
class deri: public base
{
public
virtual int func_2()
{
cout<< in func_2;
}
};

main()
{
base * ptr = new deri;
ptr-> func_2(); // ptr指向派生对象
}





我的尝试:



我尝试编译它,它抛出编译错误:

 main.cpp:在函数'int main()'中:
main.cpp : 32 6 :错误:'class base'没有名为'func_2'的成员
ptr-> func_2();
^

解决方案

哦,男孩,你有多态性和类型安全都混淆了。您期望发生的是错误的,这不是继承类型的原因。继承从父对象到子对象。因此,父类中的函数是保证的 - 让我们忽略继承中的访问修饰符一分钟 - 在子类型中,但不是相反。您无法从父类型调用子函数。父类型只是不知道该函数是什么。所以,

  class  Foo {
int a;
int b;
};

class Bar {
string name;
};

在上面的代码中,你可以这样做,

 Bar b; 
cout<< b.a; // a来自Foo

但你不能这样做,

 Foo f; 
cout<< f.name; // 名称不存在

但是,在继承中,多态性工作得很好。所以在你的代码中,如果我们这样做,

  class  deri: public  base 
{
public
int func_1()覆盖 // < - - 让我们覆盖,因为基础有虚拟
{
cout<< 派生的func_1;
return 0 ; // < - 你为什么忘记这一点而没有抱怨?
}



现在,当你运行相同的代码时,

 base * base =  new  deri; 
base-> func_1();

它会打印Derived func_1。为什么?因为多态性。



我不想让你沉迷于C ++内存模型的细节,因为所有这些细节都在那里应用。请记住,继承从父到子工作,但是多态会强制函数调用在实际的实例类型上完成 - 在你的情况下 new deri;



请参阅以下链接,了解更多有关此概念的信息,

多态(计算机科学) - 维基百科 [ ^ ]

类型安全 - 维基百科 [ ^ ]

记忆模型 - cppreference.com [ ^ ]

c ++ - 继承实际上如何工作? - Stack Overflow [ ^ ]

友谊和继承 - C ++教程 [ ^ ]


为了制作多态性工作方法名称(和签名)必须相同。由于 ptr 一个实际的 deri 指针,你仍然可以访问它的 func_2 通过向下转换的方法,但这不是多态:

  #include   <   iostream  >  
使用 命名空间标准;

class base
{
public
virtual void func_1()
{
cout<< 在base.\
的func_1中
;
}
};
class deri: public base
{
public
virtual void func_1()< span class =code-keyword> override
{
cout<< 在衍生物的func_1中;
}
虚拟 void func_2()
{
cout<< 在衍生物的func_2中;
}

};

int main()
{
base * ptr = new 衍生;
ptr-> func_1(); // ptr指向派生对象
(dynamic_cast< deri *>(ptr)) - > func_2(); // 但这不是多态性。
}


Please experts clear my doubts.
I don't understand why it throws compilation error. These are polymorphic classes, in main I assigned base pointer with a derived class pointer, it should find func_2 as __vptr of base will point to __vtable of derived class.
Or I have some gap in my understanding of __vtable and __vptr.
Please suggest me some good articles to clear my below doubts.

class base
{
  public:
     virtual int func_1()
       {
         cout << "In func_1" ;
       }
};
class deri: public base
{
    public:
        virtual int func_2()
        {
          cout << "in func_2"; 
        }
};

main()
{
 base *ptr = new deri;
 ptr->func_2();//ptr is pointing to derived object
}



What I have tried:

I tried compiling it, it throws compilation error:

main.cpp: In function ‘int main()’:
main.cpp:32:6: error: ‘class base’ has no member named ‘func_2’
 ptr->func_2();
      ^

解决方案

Oh boy, you got polymorphism and type safety all confused up there. What you are expecting to happen is wrong, that is not why a type is inherited. Inheritance works from parent, to child. So a function in parent, is guaranteed—let's ignore the access modifiers in inheritance for a minute—in the child type, but not the other way around. You cannot call a child function from a parent type. Parent type just doesn't know what that function is. So,

class Foo { 
   int a;
   int b;
};

class Bar {
   string name;
};

In the code above, you can do this,

Bar b;
cout << b.a; // a comes from Foo

But you cannot do this,

Foo f;
cout << f.name; // name does not exist

But, in inheritance, polymorphism works just fine. So in your code, if we do this,

class deri : public base
{
public:
    int func_1() override  // <-- let's override, since base has it virtual
    {
        cout << "Derived func_1";
        return 0; // <-- Why did you forget this and didn't complain? 
    }


Now, when you run the same code,

base* base = new deri;
base->func_1();

It would print, "Derived func_1". Why? Because of polymorphism.

I do not want to indulge you in the details of C++ memory model, because all this detail is applied there. Just remember, inheritance works from parent to child, but polymorphism forces that the function calls be done on the actual instance type—in your case new deri;.

Please see the links below, to learn a bit more on this concept,
Polymorphism (computer science) - Wikipedia[^]
Type safety - Wikipedia[^]
Memory model - cppreference.com[^]
c++ - How does inheritance actually work? - Stack Overflow[^]
Friendship and inheritance - C++ Tutorials[^]


In order to make polymorphism work the method name (and signature) must be the same. Being ptr a actual deri pointer, you might still access its func_2 method via downcast, but that's not polymorphism:

#include <iostream>
using namespace std;

class base
{
  public:
     virtual void func_1()
       {
         cout << "In func_1 of base.\n" ;
       }
};
class deri: public base
{
    public:
        virtual void func_1() override
        {
          cout << "in func_1 of deri.\n";
        }
        virtual void func_2()
        {
          cout << "in func_2 of deri.\n";
        }

};

int main()
{
 base *ptr = new deri;
 ptr->func_1();//ptr is pointing to derived object
 (dynamic_cast<deri *>(ptr))->func_2(); // this is not polymorphism, though.
}


这篇关于编译错误的原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆