c++中只有使用指针才能多态吗?普通实例和引用为啥不能多态?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++中只有使用指针才能多态吗?普通实例和引用为啥不能多态?相关的知识,希望对你有一定的参考价值。

父类:Father 子类:Childm_childAttr
func(/*const*/ Father ¶)//这里和const无关,但是我还是习惯在以类为参数时加上const和引用

Child c;

c.m_childAttr = ((Child)para).m_childAttr;//编译不通过,报错的意思大概是“没有定义Father到Child的强转”
c.m_childAttr = ((Child*)(&m_para))->m_childAttr;//编译通过。先取地址变成指针,再强转为指向Child的指针,从而访问Father没有的属性


func(/*const*/ Father ¶)应为func(/*const*/ Father para)

多态是和继承联系在一起的,指针是指向一段内存地址,所以可以实现父类的指针指向子类的对象。因为指向的地址都是一个,只不过所容纳的内容有大有小。从子类的内容(大的)取出父类的内容(小的)是可以的,也就是父类的指针指向子类的对象是可行的,反之则不行,因为父类的小,反过来就会有一段内存是空的或者其它不定的内容。追问

关于“指针能多态,而普通变量不能”说得很清楚,我明白了。
引用的本质跟指针一样,能不能多态呢?为什么我那段代码用引用来多态就报错?

追答

引用和指针看上去很多效果是一样的,其实是不同的。引用是别名,也就是一个东西叫几个不同的名字。所以一个对象不可能即是爸爸又是儿子,所以是不能多态的。

参考技术A C++中,实现多态有以下方法:虚函数,抽象类,覆盖,模板(重载和多态无关)。
虚函数是指在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) 函数体;实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。
C++为了让一个类成为抽象类,至少必须有一个纯虚函数。包含至少一个纯虚函数的类视为抽象类。
参考技术B

C++不是只有指针才能多态。

 

多态主要有两种方法实现:

    基类的指针加上虚函数;

    基类的引用加上虚函数。

也就是说可以用引用实现多态,但是都必须使用虚函数。

参考技术C C++用函数指针实现多态,动态编译寻找你要调用的方法,其他语言如java、C#底层多态实现机制其实都是函数指针,只是功能封装丰富了 参考技术D 引用和指针都可以

c++中重载输出操作符,为啥要返回引用

针对:ostream & operator <<(ostream & os, const ClassType &object)

说明几点:

1.第一个形参为对ostream对象的引用,在该对象上将产生输出,ostream为非const,因为写入到流会改变流的状态;该形参是一个引用,因为不能复制ostream对象(在c++中定义的标准输入输出流类istream和ostream,其中拷贝构造函数和赋值操作符函数都被放置在了private部分,且只有声明,没有定义)。

2.第二个形参一般应是对要输出的类类型的引用,该形参是一个引用以避免复制实参,减少一次拷贝;它设为const,因为输出一般不会改变该对象,设为const就可以用来输出const对象和非const对象。

3.返回类型是一个ostream引用,它的值通常是输出操作符所操作的ostream对象,首先因为ostream对象不能复制,所以必须是引用;其次引用可以少一次拷贝,提高效率;最后,为了体现连续性,实现连续输出,达到用多个输出操作符操作一个ostream对象的效果,如果不是引用,程序返回的时候就会生成新的临时对象,也就是说,连续的两个<<操作符实际上是针对不同对象的,这就好比cout<<a<<b;与cout<<a;cout<<b;的区别。

PS: 重载赋值操作符,连续赋值可以不返回引用

重载加法操作符,连续相加不能返回引用
参考技术A 因为这样才能实现诸如cout<<b<<c的级联操作

以上是关于c++中只有使用指针才能多态吗?普通实例和引用为啥不能多态?的主要内容,如果未能解决你的问题,请参考以下文章

virtual 函数只有在用指针或引用的方式访问,才会导致多态。

C++ 多态静态可变子函数指针

关于C++基类、派生类的引用和指针

引用指针和 C++ 多态性

c++中为啥要用new 函数()实现多态?

C++ 类指针