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
- 基礎拾遺---委託,匿名函式,lambda函式
- 2萬字 | 前端基礎拾遺90問前端
- 瑣碎記錄
- iOS底層原理 runtime-object_class拾遺基礎篇--(6)iOSObject
- C語言瑣碎知識C語言
- 【C++】 68_拾遺: 令人迷惑的寫法C++
- iOS底層原理 runtime- objc_msgSend拾遺基礎篇--(7)iOSOBJGse
- 關於http的瑣碎筆記HTTP筆記
- 瑣碎的想法(五)for 的前世今生
- [MASM拾遺]OffsetASM
- 前端技能拾遺前端
- Java Web 拾遺JavaWeb
- c++語法拾遺,一些細節與特性C++
- 物件導向拾遺物件
- OrchardCore Headless建站拾遺
- [C#.NET 拾遺補漏]11:最基礎的執行緒知識C#執行緒
- Confluence 容器化使用拾遺
- docker拾遺-之再入坑Docker
- 容器化 Confluence 使用拾遺
- golang拾遺:嵌入型別Golang型別
- 基於gin的golang web開發:Gin技術拾遺GolangWeb
- PHP 使用 Kafka 安裝拾遺PHPKafka
- AS拾遺--向PM學習二
- golang拾遺:指標和介面Golang指標
- 瑣碎的想法(三)對Java的批評的看法Java
- 課時39:類與物件:拾遺物件
- C#拾遺補闕【01】:字串C#字串
- 基礎拾遺:除了&和&&的區別,你還要知道位運算的這5個運算子
- 重拾java基礎之內部類Java
- 【105天】前端碎片知識拾遺00003前端
- 【106天】前端碎片知識拾遺00004前端
- JAVA 拾遺 — CPU Cache 與快取行Java快取
- Zepto核心模組之工具方法拾遺
- JSON實戰拾遺之數字精度JSON
- mysql 拾遺提高(函式、事務、索引)MySql函式索引
- React拾遺:Render Props及其使用場景React