Effective c++ 第二章总结

5.了解C++默默编写并调用哪些函数。
当你定义一个空类,c++默认会给你加上一些函数,但是惟有当这些函数被需要(被调用),它们才会被编译器创建出来。如下:
class CEmpty{};
相当于:
class CEmpty
{
public:
CEmpty(){..}
CEmpty(const CEmpty& rhs){...}
~CEmpty(){...}//编译器产出的析构函数没有virtual,除非基类析构函数带有virtual


CEmpty& operator=(const CEmpty& rhs){...}
};


至于copy构造函数和copy赋值操作符,编译器创建的版本只是单纯地将来源对象的每一个non-static成员变量拷贝到目标对象。


如果你打算在一个“内含引用成员”或者“内含const成员”的类内支持赋值操作,你必须自己定义 赋值操作符函数,更改引用和const
变量是不合法的。
如果基类将赋值操作符函数或者复制构造函数声明为private,编译器不会为派生类声明赋值操作符函数和复制构造函数。


6.若不想使用编译器自动生成的函数,就该明确拒绝。
如果要想让类禁用 复制构造 和 赋值操作,则必须将 “复制构造函数”和“赋值操作函数”声明为private,并且不能实现它。
例:
class HomeForSale
{
public:
...
private:
...
HomeForSale(const HomeForSale&);//只声明
HomeForSale& operator=(const HomeForSale&);//只声明
};
以上可能会报链接错误。
下面的方式不会报链接错误。
class Uncopyable
{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
class HomeForSale:private Uncopyable
{...};


总结:为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现,使用像Uncopyable这样的base class也是一种做法。


7.为多态基类声明virtual析构函数
c++明确指出,当derived class 对象经由一个base class 指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义--实际
执行时通常发生的是对象的derived成分没有被销毁。于是造成一个诡异的“局部销毁”对象,形成资源泄漏,数据破坏。
任何 class 只要带有virtual函数都几乎确定应该也有一个virtual析构函数。
如果class 不含virtual函数,通常表示它并不意图被用做一个base class.
如果一个类没有虚函数,你可以把这个类当成结构体使用,但是如果有虚函数,就会有一个虚函数表指针,这样就不能单纯的当一个结构体使用了。
如果想声明一个


总结:
a.带多态性质的base classes应该声明一个virtual析构函数。如果class带有任何virtual函数,就应该拥有一个virtual析构函数。
b.classes的设计目的如果不是作为base classes使用,或不是为了具备多态性,就不该声明virtual析构函数。




8.别让异常逃离析构函数。
析构函数如何处理异常的例子:
class DBConnection
{
public:
...
static DBConnection create();//这个函数返回DBConnection对象
void close();
};


class DBConn //这个class用来管理DBConnection对象
{
public:
...
~DBConn() //确保数据库连接总是会被管理
{
db.close();
}
private:
DBConnection db;
};


DBConn dbc(DBConnection::create());//dbc被析构会关闭数据库连接


异常处理的几种不同方式:
DBConn::~DBConn()
{
try{db.close}
catch(...)
{
...
std::abort();
}
}


DBConn::~DBConn()
{
try{db.close();}
{
...
}
}


class DBConn
{
public:
...
void close()
{
db.close();
closed=true;
}
~DBConn()
{
if(!closed)
{
try
{
db.close();
}
catch(...)
{...}
}
}
};


总结:
a.析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕获任何异常,然后吞下它们或结束程序。
b.如果客户需要对某个操作函数运行期间抛出异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该函数。




9.绝不在构造和析构过程中调用virtual函数。
总结:在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层)


10.令operator=返回一个reference to *this。
11.在operator=中处理“自我赋值”。
Widget& Widget::operator=(const Widget& rhs)
{
if(this!=&rhs)
{
delete pb;
pb=new Bitmap(*rhs.pb)
}
return *this;
}


12.复制对象时勿忘记其每一个成分。
任何时候只要你承担起“为derived class撰写copying函数”的重责大任,必须很小心地也复制其base class成分。
Customer为基类 PriorityCustomer为派生类。
PriorityCustomer::PriorityCustomer(const PriorityCustomer &rhs)
:Customer(rhs),
priority(rhs.priority)
{
...
}


PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
Customer::operator=(rhs);
priority=rhs.priority;
return *this;
}


总结:
a.copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”。
b.不要尝试以某个copying函数实现另外一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值