程序代码:
#include <iostream>
#include <stdexcept>
#include <cassert>
struct point
{
int x, y;
point() : x(0), y(0)
{
}
point( int x, int y ) : x(x), y(y)
{
}
};
std::ostream& operator<<( std::ostream& os, const point& pt )
{
return os << '(' << pt.x << ',' << pt.y << ')';
}
// 之所以不用 point( int x=0, int y=0 ) 是为了防止出现 Point pt(x) 这种残疾代码
// point(point &a) 应该是 point( const point& pt ),但缺省的拷贝构造本身就合乎要求,因此不需要写
// getX这种命名多丑呀?要么 getx 或 get_x 这种广泛使用的命名,要么 GetX 这种微软钟爱的命名
// ,但在这里都不需要,因为不符合C++的习俗(C++连“属性”概念都觉得丑,不肯加,何况你这种)
// 这里用struct,而不是class,以特出这个结构的数据特征。对于struct,习俗是将成员变量放在最前面
// move 函数是不需要的,因为可以用更优雅的 pt = point(x,y) 来修改逻辑值
class arrayofpoints
{
public:
arrayofpoints( size_t size ) try : ptrs_(new point[size]), size_(size)
{
}
catch( std::bad_alloc& ) {
throw;
}
arrayofpoints( const arrayofpoints& ptrs ) try : ptrs_(new point[ptrs.size_]), size_(ptrs.size_)
{
}
catch( std::bad_alloc& ) {
throw;
}
arrayofpoints& operator=( const arrayofpoints& ptrs )
{
if( this != &ptrs )
{
delete[] ptrs_;
try {
ptrs_ = new point[ptrs.size_];
size_ = ptrs.size_;
}
catch( std::bad_alloc& ) {
throw;
}
}
return *this;
}
~arrayofpoints()
{
delete[] ptrs_;
}
point& operator[]( size_t off )
{
return ptrs_[off];
}
const point& operator[]( size_t off ) const
{
return ptrs_[off];
}
point& at( size_t off )
{
if( off >= size_ )
throw std::out_of_range("out of range");
return ptrs_[off];
}
const point& at( size_t off ) const
{
if( off >= size_ )
throw std::out_of_range("out of range");
return ptrs_[off];
}
private:
point* ptrs_;
size_t size_;
};
// 数组长度的类型,在C/C++中是size_t,不是int,你要牢牢记住
// operator new是可能抛出异常的,构造函数等中异常必须先捕获再转抛
// 一般而言,必须自定义析构函数的,也一定必须自定义拷贝构造函数和赋值函数
// 记住成员函数后面没有const修饰的,和有const修饰的,是两个不同的函数
// operator[]中不检查数组越界,at函数中必须检查数组越界,这是规矩
// 对struct/class而言,非public成员,都应该在名字尾部加下划线,这是习俗(微软的习俗不是这样)
using namespace std;
// 不要在定义通用类或函数时引入名字空间std,否则别人使用你的类或函数时就被强制引入了std。
int main( void )
{
arrayofpoints Points( 2 );
Points[0] = point(12, 56);
Points[1] = point(5, 0);
cout << Points[0] << '\n'
<< Points[1] << std::endl;
return 0;
}
// 其它更多的东西等你入门了再讲,
// 比如 arrayofpoints 这种容器类,应当实现 swap 功能,应当实现 迭代 功能
// 比如 C++14 中的“右值引用”,你得加入这样的构造函数
// 比如 既然你的是仿数组类,那么也应该做得跟数组的用法差不多。(这里面对编码要求比较高)
// ……