程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 命名白白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函數,我們又回顧了一下虛函數的用法,虛函數只對引用和指針有作用。切記!

 


基類轉換為派生類
這個不可以,這個轉換關系不存在。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved