一、簡(jiǎn)介
1 什么是 C++ 繼承
C++ 繼承是指派生類(子類)從基類(父類)繼承屬性和行為的過(guò)程。我們可以創(chuàng)建一個(gè)新的類,該類可以繼承另一個(gè)類的數(shù)據(jù)屬性和方法。
// 定義一個(gè)父類 Person
class Person {
public:
string name;
int age;
string gender;
void eat() {
cout << name << " is eating. \n";
}
};
// 定義一個(gè)子類 Student 繼承父類 Person
class Student : public Person {
public:
string school;
void study() {
cout << name << " is studying at " << school << ". \n";
}
};
在上述代碼中,我們定義了一個(gè)父類 Person 與一個(gè)子類 Student。Student 類繼承了 Person 類的屬性和方法,包括 name、age、gender 和 eat() 函數(shù)。
2 繼承的目的和作用
繼承的主要目的是代碼重用:我們可以重用現(xiàn)有的代碼,避免重復(fù)編寫相同的代碼,從而提高生產(chǎn)效率。此外,繼承還使得代碼更易于管理和維護(hù),因?yàn)槲覀兛梢酝ㄟ^(guò)繼承將代碼組織成層次結(jié)構(gòu)。
// 使用繼承創(chuàng)建 Student 對(duì)象
Student myStudent;
myStudent.name = "Tom";
myStudent.age = 18;
myStudent.gender = "Male";
myStudent.school = "ABC University";
myStudent.eat(); // 輸出 "Tom is eating."
myStudent.study(); // 輸出 "Tom is studying at ABC University."
二、定義
繼承是面向?qū)ο缶幊陶Z(yǔ)言中一種非常常見(jiàn)的概念。繼承可以讓類之間實(shí)現(xiàn)代碼重用,使得程序更加易于擴(kuò)展和維護(hù)。在 C++ 中可以使用派生類和基類來(lái)實(shí)現(xiàn)繼承。
1 派生類和基類的定義
派生類是指從一個(gè)或多個(gè)基類中派生出來(lái)的類?;愂侵冈谝粋€(gè)類繼承另一個(gè)類的語(yǔ)法中被繼承的那個(gè)類。在 C++ 中,我們可以通過(guò)如下語(yǔ)法定義一個(gè)派生類:
class DerivedClass : access-specifier BaseClass {
public:
// DerivedClass 的公有成員
protected:
// DerivedClass 的保護(hù)成員
private:
// DerivedClass 的私有成員
};
在上述代碼中DerivedClass是我們新創(chuàng)建的類的名稱,access-specifier 可以是 public、protected、或 private。BaseClass 是我們想要從中繼承屬性和方法的類,我們可以在 access-specifier 后面指定 BaseClass 的訪問(wèn)類型。
代碼示例:
定義一個(gè)派生類 DerivedPerson,從基類 Person 繼承屬性和方法 :
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
string name;
int age;
void eat() {
cout << name << " is eating.\n";
}
};
class DerivedPerson : public Person {
public:
void work() {
cout << name << " is working.\n";
}
};
int main() {
DerivedPerson p;
p.name = "John";
p.age = 30;
p.eat(); // 輸出 "John is eating."
p.work(); // 輸出 "John is working."
return 0;
}
2 公有繼承和私有繼承
C++ 中有三種類型的繼承:公有繼承、保護(hù)繼承和私有繼承。
公有繼承是最常用的繼承類型之一。在公有繼承中派生類獲得了基類的公有成員和保護(hù)成員,但是基類的私有成員不會(huì)被派生類直接訪問(wèn)。
公有繼承的用法 示例:
代碼定義一個(gè)基類 Base 和一個(gè)派生類 Derived
在Derived中使用公有繼承來(lái)繼承 Base類的屬性和方法。在 main() 函數(shù)中創(chuàng)建一個(gè)Derived對(duì)象d,然后調(diào)用 set() 和 print() 函數(shù)來(lái)設(shè)置和獲取成員變量 x 的值。需要注意的是此處通過(guò)派生類的對(duì)象訪問(wèn)了基類的公有成員 x 和 print()
#include <iostream>
using namespace std;
class Base {
public:
int x;
void print() {
cout << "Base class: x = " << x << "\n";
}
};
class Derived : public Base {
public:
void set(int n) {
x = n;
}
};
int main() {
Derived d;
d.set(10);
d.print(); // 輸出 "Base class: x = 10"
return 0;
}
除了公有繼承C++ 中還有保護(hù)繼承和私有繼承。
在保護(hù)繼承中,基類的公有成員和保護(hù)成員都成為了派生類的保護(hù)成員。
在私有繼承中,基類的公有成員和保護(hù)成員都成為了派生類的私有成員。
挑選合適的繼承類型對(duì)于代碼的設(shè)計(jì)非常重要,在實(shí)際編碼中需要仔細(xì)考慮。
三、訪問(wèn)控制
1 派生類對(duì)基類成員的訪問(wèn)權(quán)限
在C++中如果一個(gè)類派生自另一個(gè)類,則派生類可以繼承基類的成員變量和成員函數(shù)。在繼承過(guò)程中訪問(wèn)權(quán)限是非常重要的一個(gè)問(wèn)題。
有三種訪問(wèn)權(quán)限:public、protected 和 private。當(dāng)一個(gè)類派生自另一個(gè)類時(shí)繼承的訪問(wèn)權(quán)限可以通過(guò)下列三種方式指定:
- public 繼承:基類的 public 成員在派生類中保持 public 屬性,基類的 protected 成員在派生類中保持 protected 屬性,基類的 private 成員在派生類中不可訪問(wèn)。
- protected 繼承:基類的 public 和 protected 成員在派生類中都被保護(hù)起來(lái),不能被外部直接訪問(wèn)。這種方式很少使用,一般只有在繼承鏈比較復(fù)雜的時(shí)候才使用。
- private 繼承:基類的 public 和 protected 成員在派生類中均變?yōu)?private 屬性,不能被外部直接訪問(wèn)。這種方式也比較少使用,一般只有在需要從多個(gè)類中繼承同一個(gè)基類的時(shí)候才使用。
下面是一個(gè)使用 public 繼承的例子,演示了派生類對(duì)基類成員的訪問(wèn)權(quán)限:
在代碼中Derived類繼承了Base類的公有成員變量 x 和成員函數(shù) print(),以及保護(hù)成員變量y
在Derived類的成員函數(shù)中可以訪問(wèn)這些成員但是不能直接訪問(wèn) Base 類的私有成員z
#include <iostream>
using namespace std;
class Base {
public:
int x;
void print() {
cout << "Base class: x = " << x << "\n";
}
protected:
int y;
private:
int z;
};
class Derived : public Base {
public:
void set(int a, int b, int c) {
x = a;
y = b;
// z = c; 無(wú)法訪問(wèn)基類的私有成員
}
void print1() {
cout << "Derived class: x = " << x << "\n";
}
void print2() {
cout << "Derived class: y = " << y << "\n";
}
// void print3() { cout << "Derived class: z = " << z << "\n"; } 無(wú)法訪問(wèn)基類的私有成員
};
int main() {
Derived d;
d.set(1, 2, 3);
d.print(); // 輸出 "Base class: x = 1"
// cout << d.y; 無(wú)法訪問(wèn)基類的保護(hù)成員
d.print1(); // 輸出 "Derived class: x = 1"
d.print2(); // 輸出 "Derived class: y = 2"
return 0;
}
2 如何控制訪問(wèn)權(quán)限
在C++中可以使用訪問(wèn)修飾符來(lái)控制類的成員的訪問(wèn)權(quán)限。訪問(wèn)修飾符可以放到類的定義中的任何位置,而且多次使用訪問(wèn)修飾符是合法的,因?yàn)楹竺娴男揎椃麜?huì)覆蓋之前的修飾符。
- public:公有修飾符可以從類的任何地方訪問(wèn)公有成員也可以從派生類的任何地方訪問(wèn)公有成員。
- protected:保護(hù)修飾符只能從類的內(nèi)部或派生類的內(nèi)部訪問(wèn)保護(hù)成員外部不能訪問(wèn)。
- private:私有修飾符只能從類的內(nèi)部訪問(wèn)私有成員派生類的內(nèi)部不能訪問(wèn)。
下面是一個(gè)使用訪問(wèn)修飾符的例子,演示了如何控制成員的訪問(wèn)權(quán)限:
在代碼中定義了MyClass類和MyDerivedClass類。
在MyClass中使用 public、protected 和 private 三種訪問(wèn)修飾符定義了三個(gè)不同的成員變量。在MyDerivedClass中從MyClass中繼承了各種成員,并在成員函數(shù)中分別訪問(wèn)了這些成員。需要注意的是,在派生類中可以訪問(wèn)基類的 public 和 protected 成員,但是不能訪問(wèn)基類的 private 成員。
#include <iostream>
using namespace std;
class MyClass {
public:
int a; // 公有成員變量
protected:
int b; // 保護(hù)成員變量
private:
int c; // 私有成員變量
public:
void set(int x, int y, int z) {
a = x;
b = y;
c = z;
}
void print() {
cout << "a = " << a << ", b = " << b << ", c = " << c << "\n";
}
};
class MyDerivedClass : public MyClass {
public:
void setDerived(int x, int y, int z) {
// a 和 b 都是 public 和 protected 成員,可以直接訪問(wèn)
a = x;
b = y;
// c 是 private 成員,無(wú)法直接訪問(wèn)
//c = z;
}
void printDerived() {
// a 是 public 成員,可以直接訪問(wèn)
cout << "a = " << a << "\n";
// b 是 protected 成員,在派生類的內(nèi)部可以訪問(wèn)
cout << "b = " << b << "\n";
// c 是 private 成員,無(wú)法直接訪問(wèn)
//cout << "c = " << c << "\n";
}
};
int main() {
MyClass obj;
obj.set(1, 2, 3);
obj.print();
MyDerivedClass obj2;
obj2.setDerived(4, 5, 6);
obj2.printDerived();
return 0;
}
四、虛函數(shù)繼承
1 繼承中的虛函數(shù)機(jī)制
在C++ 中如果一個(gè)類有虛函數(shù),那么當(dāng)這個(gè)類被繼承時(shí)在派生類中也會(huì)有虛函數(shù)表 (V-Table)。當(dāng)使用基類指針或引用指向一個(gè)派生類對(duì)象時(shí)會(huì)根據(jù)虛函數(shù)表找到正確的虛函數(shù)。這種機(jī)制被稱為動(dòng)態(tài)聯(lián)編,也就是運(yùn)行時(shí)多態(tài)或后期綁定。
代碼中定義了一個(gè)Base
類和一個(gè) Derived
類。在 Base
類中有一個(gè)虛函數(shù) print()
。Derived
類繼承了Base
類并重寫了 print()
函數(shù)。在 main()
函數(shù)中創(chuàng)建了 Derived
類的對(duì)象 d
并使用 Base
類的指針 b_ptr
指向它,然后調(diào)用 print()
函數(shù)輸出了 "Derived"
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base\n";
}
};
class Derived : public Base {
public:
void print() override {
cout << "Derived\n";
}
};
int main() {
Derived d;
Base* b_ptr = &d;
b_ptr->print(); // Derived
return 0;
}
2 在派生類中重寫虛函數(shù)
派生類可以通過(guò)重寫基類中的虛函數(shù)來(lái)改變其行為
在代碼中使用了上一個(gè)示例中的 Base
類和 Derived
類并在 Derived
類中重寫了print()
函數(shù)
在 main()
函數(shù)中通過(guò)Base
類和Derived
類的指針調(diào)用 print()
函數(shù)。當(dāng)使用 Base
類指針 b_ptr2
指向 Base
類的對(duì)象時(shí),調(diào)用的是 Base
類中的 print()
函數(shù),輸出了 "Base"
。當(dāng)使用 Base
類指針 b_ptr
指向 Derived
類的對(duì)象時(shí),調(diào)用的是 Derived
類中的 print()
函數(shù),輸出了 "Derived"
。
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base\n";
}
};
class Derived : public Base {
public:
void print() override {
cout << "Derived\n";
}
};
int main() {
Derived d;
Base* b_ptr = &d;
b_ptr->print(); // Derived
Base base;
Base* b_ptr2 = &base;
b_ptr2->print(); // Base
return 0;
}
五、多重繼承
在C++ 中一個(gè)派生類可以同時(shí)繼承多個(gè)基類,這種繼承方式被稱為多重繼承。
1 語(yǔ)法實(shí)現(xiàn)
多重繼承是指一個(gè)派生類可以同時(shí)繼承多個(gè)基類,其中每個(gè)基類可以有自己的成員函數(shù)和成員變量。一個(gè)類可以聲明對(duì)多個(gè)基類的繼承方式語(yǔ)法如下:
class Derived : access-specifier Base1, access-specifier Base2, ... {
// Derived class members and functions
};
其中,access-specifier
指定了基類成員在派生類中的訪問(wèn)權(quán)限,可以用 public
、protected
或 private
指定。如果沒(méi)有指定,則默認(rèn)為 private
。
2 派生類和基類成員的訪問(wèn)規(guī)則
在多繼承中派生類對(duì)象同時(shí)包含多個(gè)基類對(duì)象的數(shù)據(jù)成員和成員函數(shù)。根據(jù)繼承方式的不同,基類成員的訪問(wèn)規(guī)則也會(huì)有所不同。
2.1 共同基類的繼承
如果多個(gè)基類都派生自同一個(gè)基類,那么這個(gè)基類的數(shù)據(jù)成員和成員函數(shù)只會(huì)在派生類中出現(xiàn)一次。在訪問(wèn)這個(gè)基類的成員時(shí),將使用這個(gè)共同基類的數(shù)據(jù)成員和成員函數(shù)。
代碼示例:
在代碼中創(chuàng)建了 Animal
、Mammal
、Dog
、Cat
和 PersianCat
類。Mammal
和 Cat
都是直接繼承自 Animal
,Dog
和 PersianCat
分別是直接繼承自 Mammal
和 Cat
。在 PersianCat
類中同時(shí)使用了 Cat
和 Mammal
作為基類
在 main()
函數(shù)中創(chuàng)建了一個(gè) PersianCat
對(duì)象,并調(diào)用了它的 show_info()
函數(shù)。在這個(gè)函數(shù)中調(diào)用了 Animal
、Mammal
和 Cat
這三個(gè)基類的一些成員函數(shù),它們分別是在不同的層級(jí)中定義的。由于它們都繼承自共同的基類 Animal
,因此在訪問(wèn)這個(gè)基類的成員時(shí),它們都使用同一個(gè) Animal
對(duì)象的數(shù)據(jù)成員和成員函數(shù)。在控制臺(tái)輸出中可以看到不同的動(dòng)物都調(diào)用了正確的成員函數(shù)
#include <iostream>
using namespace std;
class Animal {
public:
void eat() {
cout << "Animal is eating\n";
}
};
class Mammal : public Animal {
public:
void run() {
cout << "Mammal is running\n";
}
};
class Dog : public Mammal {
public:
void bark() {
cout << "Dog is barking\n";
}
};
class Cat : public Animal {
public:
void meow() {
cout << "Cat is meowing\n";
}
};
class PersianCat : public Cat, public Mammal {
public:
void show_info() {
eat(); // 使用Animal中的eat()函數(shù)
run(); // 使用Mammal中的run()函數(shù)
meow(); // 使用Cat中的meow()函數(shù)
cout << "A Persian cat\n";
}
};
int main() {
PersianCat persian_cat;
persian_cat.show_info();
return 0;
}
2.2 不同基類的繼承
當(dāng)派生類繼承了多個(gè)不同的基類時(shí),會(huì)出現(xiàn)基類成員的二義性,需要使用作用域解析運(yùn)算符來(lái)解決。
代碼示例:
代碼中創(chuàng)建了 A
、B
和 C
類。C
類同時(shí)繼承自 A
和 B
。在 C
類的 show_info()
函數(shù)中,我們使用作用域解析運(yùn)算符 ::
來(lái)指定調(diào)用哪個(gè)基類的 func()
函數(shù)。在 main()
函數(shù)中,我們創(chuàng)建了 C
對(duì)象,并調(diào)用了它的 show_info()
函數(shù)。在控制臺(tái)輸出中可以看到它分別調(diào)用了兩個(gè)基類的 func()
函數(shù)。
#include <iostream>
using namespace std;
class A {
public:
void func() {
cout << "class A" << endl;
}
};
class B {
public:
void func() {
cout << "class B" << endl;
}
};
class C : public A, public B {
public:
void show_info() {
A::func();
B::func();
}
};
int main() {
C c;
c.show_info(); // class A \n class B
return 0;
}
六、小結(jié)回顧
C++中訪問(wèn)控制通過(guò) public、protected 和 private 關(guān)鍵字來(lái)實(shí)現(xiàn)。public 表示公開(kāi)的可以被任何地方訪問(wèn)。protected 表示受保護(hù)的只有本類和其子類可以訪問(wèn)。private 表示私有的只有本類可以訪問(wèn)。
C++中的虛函數(shù)繼承可以實(shí)現(xiàn)多態(tài)性。子類可以重載父類的虛函數(shù),并且子類的對(duì)象可以看做是父類的對(duì)象從而實(shí)現(xiàn)多態(tài)性。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-437123.html
多重繼承是 C++ 中的一個(gè)重要特性允許一個(gè)類從多個(gè)基類中繼承屬性和方法。在實(shí)現(xiàn)上如果一個(gè)類同時(shí)繼承了多個(gè)基類就可能出現(xiàn)菱形繼承問(wèn)題。為了避免這種問(wèn)題C++ 提供了虛繼承來(lái)解決。虛繼承可以實(shí)現(xiàn)讓派生類只繼承一份基類的數(shù)據(jù)成員,從而避免數(shù)據(jù)冗余和數(shù)據(jù)不一致的問(wèn)題。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-437123.html
到了這里,關(guān)于C++ 基礎(chǔ)知識(shí) 五 ( 來(lái)看來(lái)看 面向?qū)ο蟮睦^承 上篇 )的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!