本文主要是介绍笔记三单一类设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
单一类设计
文章目录
- 单一类设计
- 两种类
- new与array new(delete)
两种类
对于类中没有指针的类,注意如下
- 数据部分放到
private
声明中 - 传参与返回值:参数尽量传递引用(效率高,值传递还需拷贝入栈),考虑是否加
const
- 不改变数据的成员函数要加
const
(如对私有数据的访问接口) - 构造函数初始化数据用初始化列表
实践:实现complex
类
#ifndef COMPLEX_H
#define COMPLEX_H#include <iostream>class myComplex;myComplex& __doapl(myComplex*, const myComplex&);class myComplex
{
public:myComplex(double r = 0, double i = 0) : re(r), im(i) {} // 带参构造函数,具有默认值,用初始列表初始化myComplex& operator+=(const myComplex&); // 重载 += 运算符,接受const&,返回&double real() const { return re; } // 不改变数据,声明为const常函数 double imag() const { return im; }private:double re, im; // 数据设置为privatefriend myComplex& __doapl(myComplex*, const myComplex&); // 友元函数可以直接访问myComplex的数据
};inline myComplex& __doapl(myComplex* ths, const myComplex& r)
{ths->re += r.real();ths->im += r.imag();return *ths;
}inline myComplex& myComplex::operator+=(const myComplex& r)
{return __doapl(this, r);
}// 全局函数,重载+,复数加复数,结果是局部的,的不能返回引用
// !这里还需重载(const myComplex& x, double y)等版本
inline myComplex operator+(const myComplex& x, const myComplex& y)
{return myComplex(x.real()+y.real(), x.imag()+y.imag()); // 返回局部对象
}// 重载<<
std::ostream& operator<<(std::ostream& os, const myComplex& r)
{return os << '(' << r.real() << ',' << r.imag() << ')';
}#endif
对于类存在指针的类
实现深拷贝
- 必须重写拷贝构造函数
- 必须重写拷贝赋值函数(
operator=()
) - 重写拷贝构造函数要检测自我赋值(
this==&object
),因为要先delete,所以一定要保证不是自我赋值
实践:重写string
#ifndef _MYSTRING_
#define _MYSTRING_#include <iostream.h>
#include <string.h>class String
{
public:String(const char* cstr = 0);String(const String& str); // 拷贝构造函数String& operator=(const String& str); // 拷贝赋值函数~String(); // 析构函数char* get_cstr() const { return m_data; }
private:char* m_data;
};inline String::String(const char* cstr = 0)
{if (cstr){m_data = new char[strlen(cstr) + 1];strcpy(m_data, cstr);}else{m_data = new char[1];m_data[0] = '\0';}
}inline String::~String()
{delete[] m_data;
}inline String::String(const String& str)
{m_data = new char[strlen(str.m_data + 1];strcpy(m_data, str.m_data);
}inline String& String::operator=(const String& str)
{if (this == &str) // 检测自我赋值{return *this;}delete[] m_data;m_data = new char[strlen(str.m_data + 1];strcpy(m_data, str.m_data);return *this;
}ostream& operator<<(ostream& os, const String& str)
{return os << str.get_cstr();
}#endif
new与array new(delete)
-
new [] 搭配了delete而不是delete []造成内存泄漏
new String[3]
delete [] p;
delete先调用析构函数,再释放内存,根据上下的
cookie
delete
能够释放p指向的3个String所在的内存空间但内存中有一个字节记录申请的对象个数,如果
delete[] p
将调用3次析构函数,释放String对象中指针所指空间,如果delete p
将只调用一次析构函数,造成另外两个String中指针所指空间内存泄漏所以必须搭配使用
这篇关于笔记三单一类设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!