C++基礎::拾遺&&瑣碎
hpp vs cpp
hpp:類宣告(declaration)
cpp:類實現(definition)
拷貝構造存在的前提
忽然想到這麼一個有意思的話題,拷貝構造(copy ctor)或者賦值構造(assignment ctor)存在的前提是存在一個別的什麼構造比如預設構造或者一個含引數的構造,總之,你不能空手套白狼。
異常會中斷後續程式的進行
int main(int, char**)
{
try
{
throw std::exception("hello exception");
std::cout << "you cannot see me!" << std::endl;
// 這句話不會被執行
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
default constructor
class A
{
public:
A() { std::cout <<"A::A()" << std::endd;}
};
class B
{
public:
A _a;
};
int main(int, char**)
{
B b;
// 會在控制檯介面列印"A::A()"
// 證明預設建構函式會初始化每一位成員變數
return 0;
}
要特別注意的是,初始化每一位成員變數用的是其成員變數自身的預設建構函式
class A
{
public:
A(int) { cout << "A::A(int)" << endl;}
// 顯式提供給類一個建構函式之後,
// 編譯器會收回為它提供的那些預設建構函式(無參建構函式)
}
class B
{
private:
A _a;
}
int main(int, char**)
{
B b;
// 此時編譯出錯
// B的預設建構函式初始化其成員變數時,未找到其無參預設建構函式
return 0;
}
編譯器就是這麼矯情,如果你提供了另外的建構函式,無論是含參的還是copy 構造或是賦值構造,它就不會在為你提供預設構造。
我們再來看一個更為典型的例子:
class Widget
{
public:
Widget(){ cout << "Widget::Widget()" << endl;}
}
class Test
{
private:
shared_ptr<Widget> _widget;
public:
shared_ptr<Widget> widget() { return _widget;}
const shared_ptr<Widget> widget() const { return _widget;}
}
int main(int, char**)
{
Test t;
// 什麼也沒有輸出
// t的預設建構函式會初始化會分別呼叫其成員函式的預設建構函式
// shared_ptr<Widget>物件型別的預設建構函式不僅不會呼叫
// Widget的預設建構函式,而且是什麼也不做,這一點可參閱其原始碼
return 0;
}
這就牽涉到智慧指標物件的構造問題了,呼叫一個其預設建構函式什麼工作也不會做,只有當拷貝構造,或者賦值構造發生時,才會進行真正的構造工作:
int main(int, char**)
{
Test t;
shared_ptr<Widget> w(new Widget);
t.widget() = w;
return 0;
}
friend
一個類內部的有友元函式宣告不是類內部的一部分,因此不受訪問修飾的影響,放在一個類宣告的任何位置都是等效的。
繼承關係中的父類的虛擬函式
繼承關係中的父類的非純虛擬函式要給出實現。
class Base
{
public:
void foo(); // 可以不給出實現,但當呼叫Base物件(如果Base不是抽象基類)的foo函式時才會發生解析錯誤
virtual void fooA(){} // 只有派生類A才能使用的介面
virtual void fooB(){} // 只有派生類B才能使用的介面
virtual void func() = 0; // 子類必須提供該純虛擬函式的實現方可進行例項化
};
class DerivedA :public Base
{
public:
void fooA() {}
void func() {}
}
class DeriveB :public Base
{
public:
void fooB() {}
void func() {}
}
int main(int, char**)
{
DerivedA da;
DerivedB db;
da.foo(); // 訪問基類中的foo(),前提是Base提供實現
da.fooA();
da.fooB();
return 0;
}
相關文章
- Vue.js基礎拾遺Vue.js
- 前端拾遺--javascript-ES6基礎前端JavaScript
- [Go]Go 語言基礎拾遺(一)Go
- 2萬字 | 前端基礎拾遺90問前端
- 基礎拾遺---委託,匿名函式,lambda函式
- .NET 基礎拾遺(3): 字串、集合和流字串
- C++標準庫::拾遺C++
- .NET 基礎拾遺(5):多執行緒開發基礎執行緒
- .NET 基礎拾遺(7):Web Service 的開發與應用基礎Web
- .NET基礎拾遺(1):型別語法基礎和記憶體管理基礎型別記憶體
- .NET 基礎拾遺(4):委託、事件、反射與特性事件反射
- .NET 基礎拾遺(6)ADO.NET 與資料庫開發基礎資料庫
- mongoose 拾遺Go
- C語言瑣碎知識C語言
- 【C++】 68_拾遺: 令人迷惑的寫法C++
- .NET基礎拾遺(2):物件導向的實現和異常的處理基礎物件
- iOS底層原理 runtime-object_class拾遺基礎篇--(6)iOSObject
- 關於http的瑣碎筆記HTTP筆記
- PHP那些瑣碎的知識點PHP
- 前端技能拾遺前端
- Linux拾遺Linux
- Java Web 拾遺JavaWeb
- [MASM拾遺]OffsetASM
- 物件導向拾遺物件
- 【java web】--Ajax拾遺JavaWeb
- C語言拾遺C語言
- iOS底層原理 runtime- objc_msgSend拾遺基礎篇--(7)iOSOBJGse
- [C#.NET 拾遺補漏]11:最基礎的執行緒知識C#執行緒
- c++語法拾遺,一些細節與特性C++
- 併發程式設計瑣碎知識點程式設計
- golang拾遺:嵌入型別Golang型別
- docker拾遺-之再入坑Docker
- Unix廣告拾遺 by Dennis Ritchie
- PHP 使用 Kafka 安裝拾遺PHPKafka
- AS拾遺--向PM學習二
- golang拾遺:指標和介面Golang指標
- 【演算法拾遺】階乘演算法
- 【Java學習筆記】拾遺Java筆記