命名白白c++ 基类和派生类的转换
派生类转换为基类
我们先明确几个概念,如果我理解的不对希望能有大神指出错误。
第一是,无论哪种继承方式,子类拥有父类的所有成员变量和成员函数,只是访问权的问题。举个例子
[cpp] view plaincopyprint?
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
class B:public A
{
public:
int i;
};
int main()
{
B b;
b.i = 10;
A &a = b;
cout<<a.i<<endl;
}
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
class B:public A
{
public:
int i;
};
int main()
{
B b;
b.i = 10;
A &a = b;
cout<<a.i<<endl;
}大家觉得最后输出的结果是多少?
不是10.而是一个随机值
我的电脑是1629101750。
这说明什么问题呢,B中有两个i,一个是父类的i,一个是自己的i.
但是一般程序设计的人绝对不会这么设计的,因为一般名字一样只要父类有,子类继承就可以了。
但是考试的人,就会这么出题了,这就是为什么大家写了那么多年程序,很多面试题还是没有见过,还是不会,第一是我们基础不牢固,第二是这些地方的实用性其实不是那么大,可能永远不会用到。 不过如果为了提高自己,主要是为了防止出差,很多细节还是需要研究研究,多写写代码,来验证自己的思想是不是正确。
那么派生类转换为基类怎么理解呢?
按照c++ primer 中的说法有两种形式,一种就是给基类赋值,一种是转换为基类的引用或者指针。派生类对象自身并没有变成基类对象。
这两种方式有一些细微的区别,很多时候最好使用常引用最为函数的入参,为什么呢?因为引用少了赋值的操作,效率上面会高一些。
可以查看我写的c++赋值的几种方式, , 直接赋值应该是c语言中保留下来的,在c++中它的作用似乎就不大了,尤其对类和对象的。
大家看看下面的例子
[cpp]
#include<iostream>
using namespace std;
class A
{
public:
A();
A(A &a);
A(int i);
void set(A a);
int getI();
virtual void print();
private:
int i;
};
void A::print()
{
cout<<"A print"<<endl;
}
A::A()
{
}
A::A(A& a)
{
i = a.i;
}
A::A(int i)
{
this->i = i;
}
int A::getI()
{
return i;
}
void A::set(A a)
{
i = a.i;
}
class B: public A
{
public:
B(int i);
virtual void print();
private:
int k;
int i;
};
void B::print()
{
cout<<"B print"<<endl;
}
B::B(int i)
{
i = 5;
}
int main()
{
A a(10);
B b(5);
A a1(a);
A a2(b);
cout<<a1.getI()<<endl;
cout<<a2.getI()<<endl;
A a_next(20);
B b_next(15);
a1.set(a_next);
a2.set(b_next);
cout<<a1.getI()<<endl;
cout<<a2.getI()<<endl;
A &a3(b);
a1.print();
a2.print();
a3.print();
}
#include<iostream>
using namespace std;
class A
{
public:
A();
A(A &a);
A(int i);
void set(A a);
int getI();
virtual void print();
private:
int i;
};
void A::print()
{
cout<<"A print"<<endl;
}
A::A()
{
}
A::A(A& a)
{
i = a.i;
}
A::A(int i)
{
this->i = i;
}
int A::getI()
{
return i;
}
void A::set(A a)
{
i = a.i;
}
class B: public A
{
public:
B(int i);
virtual void print();
private:
int k;
int i;
};
void B::print()
{
cout<<"B print"<<endl;
}
B::B(int i)
{
i = 5;
}
int main()
{
A a(10);
B b(5);
A a1(a);
A a2(b);
cout<<a1.getI()<<endl;
cout<<a2.getI()<<endl;
A a_next(20);
B b_next(15);
a1.set(a_next);
a2.set(b_next);
cout<<a1.getI()<<endl;
cout<<a2.getI()<<endl;
A &a3(b);
a1.print();
a2.print();
a3.print();
}
觉得输出的结果是什么呢?
我这里的答案是:
10
2293028
20
1628665296
A print
A print
B print
为什么呢?
子类会调用父类的默认构造函数,根据上面的内容,上题中子类中包含父类的所有元素和方法,但是父类中的默认构造函数没有初始化自己的i,这样i就是个随机值。
子类无论是给父类赋值,还是转换为父类的构造函数,父类中的i永远都没有被初始化,所以结果就是上面的内容。
后面的print函数,我们又回顾了一下虚函数的用法,虚函数只对引用和指针有作用。切记!
基类转换为派生类
这个不可以,这个转换关系不存在。
补充:软件开发 , C++ ,