C++ 编程/惯用法
外观
< C++ 编程
(从 更多 C++ 惯用法/处理主体 重定向)T::operator=处理 LHS 和 RHS 指向同一对象的情况。
T& operator= (const T& that)
{
if (this == &that)
return *this;
// handle assignment here
return *this;
}
笔记
- 请记住身份(LHS 和 RHS 是同一个对象)和相等(LHS 和 RHS 具有相同的值)之间的区别。T::operator=必须保护自己免受身份的影响,因为这样,赋值代码就可以方便安全地假设 LHS 和 RHS 指向不同的对象。
- 还有其他技术更优越,但在所有情况下都不适用。例如,如果类的所有成员T(比如,mem1, mem2, ..., memN) 提供了一个swap函数,可以使用以下代码代替
T& operator= (T that)
{
// that is constructed by the copy constructor
mem1.swap (that.mem1);
mem2.swap (that.mem2);
...
memN.swap (that.memN);
// now what were originally this->mem1, this->mem2, etc. get
// destroyed when that gets destroyed, and that.mem1, etc. are
// retained in *this
return *this;
}
“指向实现的指针”(pImpl)习语,也称为“不透明指针”习语,是一种为类提供数据并因此进一步实现抽象的方法。
在 C++ 中,您必须在类定义中声明成员变量,然后是公有的,并且必须这样做才能分配适当的内存空间,这意味着在“所有”类中都不可能实现抽象。
但是,以额外指针解引用和函数调用的代价,您可以通过指向实现的指针获得这种级别的抽象。
class Book
{
public:
void print();
private:
std::string m_Contents;
}
因此,使用 Book 类的某人只需要了解 print(),但是如果您想为 Book 类添加更多细节会怎样。
class Book
{
public:
void print();
private:
std::string m_Contents;
std::string m_Title;
}
现在,所有使用 Book 的用户都必须重新编译,因为他们知道的对象变大了,但他们仍然只调用 print()。
pImpl 将实现以下模式,以避免此问题。
/* public.h */
class Book
{
public:
Book();
~Book();
void print();
private:
class BookImpl;
BookImpl* const m_p;
}
在单独的“内部”头文件中
/* private.h */
#include "public.h"
#include <iostream>
class Book::BookImpl
{
public:
void print();
private:
std::string m_Contents;
std::string m_Title;
}
然后,Book 类的主体将类似于
Book::Book(): m_p(new BookImpl())
{
}
Book::~Book()
{
delete m_p;
}
void Book::print()
{
m_p->print();
}
/* then BookImpl functions */
void Book::BookImpl::print()
{
std::cout << "print from BookImpl" << std::endl;
}
然后从主函数调用
int main()
{
Book b;
b.print();
}
您还可以使用 std::unique_ptr<BookImpl> 或等效项来管理内部指针。