C++和其它OOP语言一样,当你定义一个class时就等于定义了一个新type,所以对于一个新type应该带着和设计内置类型一样谨慎的态度去研讨设计。下面是需要注意的几点(对于每一点我都编写了相关的示例代码):
1、新type的对象应该如何被创建和销毁?
即是否需要定义自己的operator new、operator new[]、operator delete和operator delete[]。看一段实现自定义operator new的代码:
#include "stdafx.h"
#include <stdlib.h>
#include <string>
using namespace std;
class String {
public:
String(const char *buffer);
~String();
void* operator new(size_t size);
private:
char *_buffer;
};
String::String(const char *buffer) {
if (buffer == NULL)
return;
size_t len = strlen(buffer);
_buffer = new char[len];
strcpy(_buffer, buffer);
}
String::~String() {
if (_buffer != NULL)
delete[] _buffer;
}
void* String::operator new(size_t size) {
return ::operator new(size);
}
int _tmain(int argc, _TCHAR* argv[]) {
String str("string");
system("pause");
return 0;
}
#include "stdafx.h"
#include <stdlib.h>
#include <string>
using namespace std;
class String {
public:
String(const char *buffer);
~String();
void* operator new(size_t size);
private:
char *_buffer;
};
String::String(const char *buffer) {
if (buffer == NULL)
return;
size_t len = strlen(buffer);
_buffer = new char[len];
strcpy(_buffer, buffer);
}
String::~String() {
if (_buffer != NULL)
delete[] _buffer;
}
void* String::operator new(size_t size) {
return ::operator new(size);
}
int _tmain(int argc, _TCHAR* argv[]) {
String str("string");
system("pause");
return 0;
}
2、明确对象的初始化和对象的赋值操作有什么区别。看下面的代码:
class String {
public:
String(const char* buffer) : _buffer(0) {
_buffer = const_cast<char*>(buffer);
}
~String() {
if (_buffer != NULL)
delete[] _buffer;
}
private:
char *_buffer;
};
3、新type的对象如何被pass by value,意味着什么?通常来说copy构造函数完成pass by value。看下面的代码:
class String {
public:
String(const char* buffer) : _buffer(0) {
_buffer = const_cast<char*>(buffer);
}
String(const String& rhs) {
size_t len = rhs.Length();
_buffer = new char[len];
strcpy(_buffer, rhs.CStr());
}
~String() {
if (_buffer != NULL)
delete[] _buffer;
}
size_t Length(void) const { return strlen(_buffer); }
const char* CStr(void) const { return _buffer; }
private:
char *_buffer;
};
4、什么是新type的合法值?也就是确保成员变量调用所谓的访问函数时提供的合法性。看下面的代码(通过size_t类型的约束至少可以确保分配的大小不会申请是负数,因为这样毫无意义):
class String {
public:
String(const char* buffer) : _buffer(0) {
_buffer = const_cast<char*>(buffer);
}
String(const String& rhs) {
size_t len = rhs.Length();
_buffer = new char[len];
strcpy(_buffer, rhs.CStr());
}
~String() {
if (_buffer != NULL)
delete[] _buffer;
}
void Realloc(size_t newSize) {
const char *oldBuffer = _buffer;
if (oldBuffer != NULL) {
_buffer = new char[newSize];
strcpy(_buffer, oldBuffer);
delete[] oldBuffer;
} else
_buffer = new char[newSize];
}
size_t Length(void) const { return strlen(_buffer); }
const char* CStr(void) const { return _buffer; }
private:
char *_buffer;
};
5、你的新type需要配合某个继承体系吗?看下面代码(如果确定某个类型为基类型,那一定要注意它的析构函数必需是virtual,以确保不会出现不必要的内存泄露):
class Windows {
public:
Windows() { }
virtual ~Windows() { }
};
class WindowsXP : private Windows {
};
6、你的新type需要什么样的转换?某些情况下希望可以隐式转换为另一个类型。看下面的代码:
#include "stdafx.h"
#include <stdlib.h>
#include <string>
using namespace std;
class Int32 {
public:
Int32(int value)
: _value(value) { }
~Int32() { }
operator int() {
return _value;
}
private:
int _value;
};
int _tmain(int argc, _TCHAR* argv[]) {
int i = Int32(5);
system("pause");
return 0;
}
7、什么样的操作符和函数对此新type而言是合理的?即某些情况是否应该使其成为友联或者不具备关系。
8、什么样的标准函数应该驳回?如果不需要编译生成的函数那就明显拒绝它。
class noncopyable {
protected:
noncopyable() { }
~noncopyable() { }
private:
noncopyable(const noncopyable&);
noncopyable& operator=(const noncopyable&);
};
9、谁该取用新type的成员?即合理的设计哪些成员是private、protected、public、friend。
10、什么是新type的未声明接口?一般来说指那些在新type内部工作的接口或类型。它对效率、异常安全性及资源运用提供保证。
11、你的新type有多么一般化?或许你定义的并不是一个type,而是定义了一个整个types家族。这个时候需要考虑使用template。比如一个通用的可变数组容器,看下面代码的简单实现:
template<typename T>
class Array {
Array() : Array(4) { }
Array(size_t capacity);
~Array() {
delete[] _arr;
}
size_t Size(void) const { return _size; }
size_t Capacity(void) const { return _capacity; }
void Add(T data);
private:
void Realloc(size_t newSize);
private:
T *_arr;
size_t _capacity;
size_t _size;
};
template<typename T>
Array<T>::Array(size_t capacity) {
*_arr = new T[capacity];
_capacity = capacity;
_size = 0;
}
template<typename T>
void Array<T>::Add(T data) {
if (_size >= _capacity)
Realloc(_capacity << 1);
*_arr[_size++] = data;
}
template<typename T>
void Array<T>::Realloc(size_t newSize) {
T *old = _arr;
_arr = new T[newSize];
_capacity = newSize;
memcpy(_arr, old, _capacity);
delete[] old;
}
11、你真的需要一个新type吗?如果只是定义一个新的派生类型以便添加一两个简单的函数,可以考虑是否template化或者在基类型中添加。
参考:Effective C++ Third Edition(Scott Meyers著)P.83 – P.86
相关推荐
Effective C++:改善程序与设计的55个具体做法(中文第三版)亚马逊图书 放到Kindle上就可以浏览学习,因为亚马逊软件有防护功能,电脑上无法使用,切记!!!!
条款19:设计class犹如设计type 条款20:宁以pass-by-reference-to-const替换Pass-by-value 条款21:必须返回对象时,别妄想返回其reference 条款22: 将成员变量声明为private 条款23: 宁以non-member、non-...
条款19:分清成员函数,非成员函数和友元函数 条款20:避免PUBLIC接口出现数据成员 条款21:尽可能使用CONST 条款22:尽量用传引用而不用传值 条款23:必须返回一个对象时不要试图返回一个引用 条款24:在函数重载与设定...
作者简介 作者:(美国)迈耶斯(Scott Meyers) 迈耶斯(Scott Meyers),二十多年来,Scott Meyers的Effective C++系列书籍(包括《Effective C++》《More Effective C++》和《Effective STL》)为C++编程语言...
当您读过《Effective C++中文版(第3版改善程序与设计的55个具体做法)》后,就获得了迅速提升自己C++功力的一个契机。 在国际上,本书所引起的反响,波及整个计算机技术出版领域,余音至今未绝。几乎在所有C++书籍...
条款19:了解暂时对象的来源 098 Understand the origin of temporary objects 条款20:协助完成「返回值优化(RVO)」 101 Facilitate the return value optimization 条款21:利用重载技术(overload)避免隐式...
学习C++ 和STL学习学习的书,三合一(共140种改善您的C++程序的经验之谈,C++程序员必读),英文原版,带书签,2018版本。难得的c++学习资料
条款19: 分清成员函数,非成员函数和友元函数 条款20: 避免public接口出现数据成员 条款21: 尽可能使用const 条款22: 尽量用“传引用”而不用“传值” 条款23: 必须返回一个对象时不要试图返回一个引用 条款24: 在...
Effective C++跟more Effective c++
条款19:设计class犹如设计type treat class design as type design. 条款20:宁以pass-by-reference-to-const替换pass-by-value prefer pass-by-reference-to-const to pass-by-value. 条款21:必须返回对象时,别...
C++: Effective Modern C++ (C++ 11, C++ 14) (guide,C Programming, HTML, Javascript, Programming,all,internet, Coding, CSS, Java, PHP Vol 1) By 作者: Paul Laurence ISBN-10 书号: 1547133244 ISBN-13 书号:...
电子版的effective c++ 和more effective c++ c++四书五经中介绍的经典书籍
中文版 chm Effective C++ More effective C++
effective c++ & more effective c++ 纯文字版
《Effective C++:改善程序与设计的55个具体做法》(中文版)(第3版)一共组织55个准则,每一条准则描述一个编写出更好的C++的方式。每一个条款的背后都有具体范例支撑。第三版有一半以上的篇幅是崭新内容,包括讨论...
Effective.C++.改善程序与设计的55个具体做法.第三版.中文.侯捷译.pdf
Effective C++:改善程序与设计的55个具体做法
Effective C++ & More Effective C++.chm
Effective c++.pdf Effective c++.pdf