IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> effective c++ -> 正文阅读

[C++知识库]effective c++

尽量以const,enum,inline 代替#define

	{
		const int arr_len = 100;
		int arr[arr_len]{ 0 };
	}
	{
		enum {
			arr_len=100
		};
		
		int arr[arr_len]{ 0 };
		
	}

尽可能使用引用传递,减少析构和构造

确定使用对象前已经被初始化

(1)使用成员初始列初始化对象
因为不这样的话构造函数会执行默认的构造,然后进行赋值操作
(2)解决垮单元初始化问题,以local static 代替no_local static

为多态基类声明vitrul 析构函数

但是vitrul会导致产生vptr,增加了对象的大小
通常是如果没有vitrual函数,则不必要析构vitrual
还有就是不派生STL的类

不让析构函数产生异常

虚函数不能再构造和析构中使用

如果自己写copying 函数,记得copying完

返回对象别妄想返回refrence

local对象会随函数的结束而销毁

将成员变量声明为private

因为一旦很多地方使用了该变量,一旦要撤销该变量时会很麻烦,例如修改函数名称啥的

尽量使用no_member ,no_friend,代替member函数,有利于封装

尽可能延后变量定义的出现

变量会占内存,同时要考虑析构和构造带来的执行效率

尽量少做转型动作

const_cast(expression) 会将expression的const转变为no_const
dynamic_cast() “向下安全转型”,增加了运行的成本
reinterpret_cast()低级转型,实际的动作和结构取决于编译器,不利于移植
static_cast() 隐式强迫转型,但是不能将const --> no_const

正确认识inline

inline 只是向编译器申请而不是命令,成功与否取决于编译器
inline 省去了函数调用的时间,但是会增加体积
在class 头文件中class声明时就实现的成员函数,默认inline
其他的在声明时inline但是实现得在头文件中

将文件间的编译依存关系降至最低

每个头文件尽可能满足自身的需要就,而不是引入其他头文件
可以分为两步:

步骤1.将需要的数据类型前置声明

#pragma once
//===================================================
//
//
//  Manager.h
//===================================================

#ifndef MANAGER_H_
#define MANAGER_H_
#include <memory>
class TC1;
class TC2;
class Manager{
	std::shared_ptr<TC1> m_tc1;
	std::shared_ptr<TC2> m_tc2;
public:
	void doSomething();
	
};
#endif // !MANAGER_H_

或者

exten class TC1;
exten class TC2;

步骤2:在实现的文件引入相应的数据类型的定义

#include "Manager.h"
#include "TC1.h"
#include "TC2.h"
void Manager::doSomething(){
	m_tc1 = std::make_shared<TC1>();
	m_tc2 = std::make_shared<TC2>();
	m_tc1->start();
	m_tc2->start();
}

确定public继承是is-a 关系

继承时注意不要遮掩继承而来的名称

举个会遮掩的例子

#pragma once
//===================================================
//
//
//  TC1.h
//===================================================

#ifndef TC1_H_
#define TC1_H_
class TC1{
public:
	TC1();
	~TC1();
	void start();
	
	void fun1(int);
	void fun1();
	void fun2(int);
	void fun2();
};
#endif // !TC1_H_

#pragma once
//===================================================
//
//
//  Manager.h
//===================================================

#ifndef MANAGER_H_
#define MANAGER_H_
#include <memory>
#include "TC1.h"
class Manager:public TC1{
	void fun1();
public:
	void doSomething();
	
};
#endif // !MANAGER_H_

void Manager::doSomething(){
	fun1();
	fun1(1);//will error 名字被遮掩了
	//解决的办法是 using::TC1::fun1; 这样如果在local这找不到fun(1)的话,就会去TC1里面找
	
}

还存在这样的一种情况,Driver不想继承Base的全部函数,也就是客户使用时候并不能使用base的所有的函数,那样继承的时候可以private,
但是吧还是有想使用的函数,考虑到使用using::Base::fun,很多会引入很多相同名字的函数,并不只是一个

#pragma once
//===================================================
//
//
//  TC1.h
//===================================================

#ifndef TC1_H_
#define TC1_H_
class TC1{
public:
	TC1();
	~TC1();
	void start();
	
	void fun1(int);
	void fun1();
	void fun2(int);
	void fun2();
};
#endif // !TC1_H_


#pragma once
//===================================================
//
//
//  Manager.h
//===================================================

#ifndef MANAGER_H_
#define MANAGER_H_
#include <memory>
#include "TC1.h"
class Manager:private TC1{
public:
	using::TC1::fun1;
	void fun1();

	
};
#endif // !MANAGER_H_

int main(int argc, char** argv) {
	Manager m;
	m.fun1();
	m.fun1(1);
	
	return 0;
}

这时我们只想引入其中的一个函数,但是我们可以使用的是两个
解决的办法是转接函数,而不是用using::TC1::fun1

//===================================================
//
//
//  Manager.h
//===================================================

#ifndef MANAGER_H_
#define MANAGER_H_
#include <memory>
#include "TC1.h"
class Manager:private TC1{
public:
	void fun1();
};
#endif // !MANAGER_H_//===================================================

#include "Manager.h"
#include "log/LogX.h"
#include "TC1.h"
#include "TC2.h"
void Manager::fun1(){
	TC1::fun1();
	
}



int main(int argc, char** argv) {
	Manager m;
	m.fun1();
	//m.fun1(1);use it will error
	
	return 0;
}


接口和缺省函数应该分离开来

(1)Base的vitrual 函数(先称为接口)一般需要Driver重新定义,但是其实现可以直接使用缺省的函数,但是原则上得分离开来,因为,很多情况,缺省得并不是我们想要的,而客户又使用了缺省,此时我们不得不思考怎们让Driver必须重新定义该接口.

常规得解决办法是,在虚函数后面加上=0 让此函数变成纯虚函数

class Base {
public:
	virtual void fun1() = 0 {
		LOGXA("default function");
	}
};

class Driver :public Base {
public:
	virtual void fun1() {//if no it function ,it will error
		LOGXA("driver function");
	}
};

int main(int argc, char** argv) {
	Driver d;
	
	return 0;
}

除了纯虚函数以外,可以使用得方法还有很多,比如增加一个额外得缺省函数,让此函数在Driver里面重新定义,(这方法不太好)

class Base {
public:
	void fun1() {
		defaultFun1();
	}
private:
	virtual void defaultFun1() {
		LOGXA("default fun");
	}
};

class Driver :public Base {
public:
	void defaultFun1() {
		LOGXA("driver fun");
	}
};

int main(int argc, char** argv) {
	Driver d;
	d.fun1();
	return 0;
}

result:
[+] log construction, can use it  E:\code\Test\_log\log.html
[0]06:45:29[info][988]  [Driver::defaultFun1]   driver fun   (TestMain.cpp:40)
[+] ~log deconstruction

还有一种方法就是fun1(fun* f=default)
这样得策略模式,让driver自己实现f

绝不重定义继承而来的no_vitrual函数

绝不修改继承而来的缺省参数值

将与参数无关的代码抽离templeta

template 需要类型转换时 请将模板定义成非成员函数

加上friend

template对类型判断后执行的方法

1.可以利用重载
2.if else 利用typeid

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:20:07  更:2022-03-22 20:21:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:34:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码