当前位置:编程学习 > C/C++ >>

命名白白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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,