关于C++中的类的学习笔记
参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第七、八章
7.自定义数据类型
7.1 结构
特点:结构中的数据类型可以是除了所定义的结构类型以外的任何类型。
例子:
//Ex7_01.cpp //Exercising structures in the yard #include <iostream> using std::cout; using std::endl; //结构定义 struct Rectangle { int left; int top; int right; int bottom; }; long area(const Rectangle & aRect)//这里的&有什么作用 { //aRect.bottom = 90;//const 类型不能改变值,会报错 return (aRect.right - aRect.left)*(aRect.bottom - aRect.top); } long area1( Rectangle & aRect)//这里去掉const 就可以改变主函数中的变量值了,说明&是对变量的直接引用而不再重新开辟空间 { aRect.bottom = 90; return (aRect.right - aRect.left)*(aRect.bottom - aRect.top); } long area2(Rectangle y)//把&去掉之后 ,尽管可以改变计算结果但是不能改变主函数中的变量值,说明这里重新复制了一个值 { y.bottom = 70; return (y.right - y.left)*(y.bottom - y.top); } int main() { Rectangle yard{ 0, 0, 100, 120 };//结构的初始化 Rectangle * pRect{&yard};//指向结构体的指针 cout << "the right of the yard is :" << pRect->right << endl;//指针对结构体成员的引用 cout << "At the begining ,the bottom of yard is :" << yard.bottom<<endl; cout << "the area of yard is :" << endl; cout << area(yard)<< endl; cout << "the area1 of yard is :" << endl; cout << area1(yard) << endl; cout << "when we remove the 'const',the bottom of yard is :" << yard.bottom << endl; cout << "the area2 of yard is :" << endl; cout << area2(yard) << endl; cout << "when we remove the '&',the bottom of yard is :" << yard.bottom << endl; return 0; }
7.2类
类是用户定义的数据类型,其包含的元素可以是基本数据类型或者其他用户定义的变量,以及函数。
类的实例叫做对象。
对象在定义中隐式地包含数据和操作数据的函数,这种思想称作封装。
类构造函数,是类的特殊函数,在创建新的类对象时调用它。
例子:
//定义类及其成员函数 #include <iostream> using std::cout; using std::endl; class CBox { public: double m_Length{ 1.0 };//这个初始化过程也可以放在构造函数列表中 double m_Width{ 1.0 }; double m_Height{ 1.0 }; //构造函数的定义 CBox()//名字必须一样,可以有多个对应多种不同的初始化方式 { cout << "default constructor called" << endl; } //这个就代表了使用默认初值,如果这里不进行一个空的定义,在主函数中写CBox box1;会报错 CBox(double lv, double wv, double hv) { cout << "constructor called" << endl; m_Length = lv; m_Width = wv; m_Height = hv; } double volume(); }; double CBox::volume()//在类的外部定义成员函数 { return m_Length*m_Height*m_Width; } int main() { CBox box1; double boxvolume{ box1.volume() }; cout << "DEFAULT box1 volume is : " << boxvolume << endl; //对类的public成员进行重新定义 box1.m_Height = 18.0; box1.m_Length = 2.0; cout << "the new box1 volume is : " << box1.volume() << endl; CBox box2{ 20.0, 80.0, 1}; cout << "the new box2 volume is : " << box2.volume() << endl; return 0; }
对于类的构造函数也可以定义成下面的形式
class CBox { public: double m_Length; double m_Width; double m_Height; //构造函数的另外一种写法,可以简洁的表示上面的过程,效果是一样的 CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) : m_Length{ lv }, m_Width{ wv }, m_Height{ hv } { cout << "constructor called " << endl; } double volume(); };
类的析构函数,用来销毁不再需要或者超出其作用域的对象。如果类成员占用的空间是构造函数中动态分配的,就必须自定义析构函数。
例子:
//验证析构函数的作用 //#include <iostream> #include <iostream> using std::cout; using std::endl; class CBox { public: //析构函数 ~CBox() { cout << "Destructor called" << endl; } //构造函数 explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) : m_Length{ lv }, m_Width{ wv }, m_Height{ hv } { cout << "constructor called " << endl; } double volume() const; bool compare(const CBox* pBox) const; private: double m_Length; double m_Width; double m_Height; }; bool CBox::compare(const CBox* pBox) const { if (!pBox) { return false; } return this->volume() > pBox->volume(); } double CBox::volume() const//在类的外部定义成员函数 { return m_Length*m_Height*m_Width; } int main() { CBox cigar{ 8, 5.0, 1 }; CBox match{ 2.2, 1.1, 0.5 }; CBox * pB1{ &cigar }; CBox * pB2{ &match }; cout << "volume of cigar is " << pB1->volume() << endl; cout << "volume of match is " << pB2->volume() << endl; cout << "return of the compare() is " << pB1->compare(pB2) << endl; return 0; }
类模板,类模板本身不是类,而只是编译器用来生成类代码的一种方法。通过指定<T>中T的类型来确定希望生成的类。
//熟悉类模板的使用 #include <iostream> #include <utility> // #include <algorithm>//MAX MIN using std::cout; using std::endl; using namespace std::rel_ops;//这个玩意儿就在utility中 class CBox { public: ~CBox() { //cout << "destructor called" << endl; } explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0) : m_Length{ lv }, m_Width{ wv }, m_Height{ hv } { cout << "constructor called " << endl; if (m_Height > m_Length) { std::swap(m_Height, m_Length); std::swap(m_Width, m_Height); } else if (m_Height > m_Width) { std::swap(m_Height, m_Width); } } double volume() const { return m_Length*m_Height*m_Width; } //运算符重载 bool operator<(const CBox& aBox) const { return this->volume() < aBox.volume(); } bool operator<(const double value) const { return this->volume() < value; } bool operator>(const CBox& aBox) const { return this->volume() > aBox.volume(); } bool operator>(const double value) const { return this->volume() > value; } bool operator==(const CBox& aBox) const { return this->volume() == aBox.volume(); } CBox operator+(const CBox& aBox) const { return CBox(std::max(m_Length, aBox.m_Length), std::max(m_Width, aBox.m_Width), m_Height + aBox.m_Height); } void showBox() const { cout << m_Length << "" << m_Width << "" << m_Height << endl; } private: double m_Length; double m_Width; double m_Height; }; //CSamples class template definition,用来存储CBox样本的 template <typename T> class CSamples { public: CSamples(const T values[], int count); CSamples(const T& value); CSamples(T&& value);//两个&代表rvalue 引用 CSamples() = default; bool add(const T & value); bool add(T&& value); T max() const; private: static const size_t maxSamples{ 100 }; T m_Values[maxSamples]; int m_Next{}; }; //在类模板外部定义其函数 template <typename T> CSamples <T>::CSamples(const T values[], int count) { m_Next = count < maxSamples ? count : maxSamples; for (int i{}; i < m_Next; i++) { m_Values[i] = values[i]; } } template <typename T> CSamples <T>::CSamples(const T& value) { m_Next = 1; m_Values[0] = value; } template <typename T> CSamples <T>::CSamples( T && value) { cout << "move constructor" << endl; m_Next = 1; m_Values[0] = std::move(value); } template <typename T> bool CSamples<T>::add(const T& value) { cout << "add." << endl; bool OK{ m_Next < maxSamples }; if (OK) m_Values[m_Next++] = value; return OK; } template <typename T> bool CSamples<T>::add( T&& value) { cout << "add move" << endl; bool OK{ m_Next < maxSamples }; if (OK) m_Values[m_Next++] =std::move(value); return OK; } template <typename T> T CSamples<T>::max() const { T themax{ m_Values[0] }; for (int i{ 1 }; i < m_Next; i++) { if (themax < m_Values[i]) { themax = m_Values[i]; } } return themax; } int main() { CBox boxes[]{ CBox{ 8.0, 5.0, 2.0 }, CBox{ 5, 4, 6 }, CBox{4,3,3} }; CSamples<CBox> myBoxes{ boxes, _countof(boxes) };//创建CBox类型的类 CBox maxBox{ myBoxes.max() }; cout << "the biggest box has a volume of " << maxBox.volume() << endl; //加入新的对象 CSamples<CBox> moreBoxes{ CBox{ 8, 5, 2 } }; moreBoxes.add(CBox{ 5, 8, 6 }); moreBoxes.add(CBox{ 4, 3, 3 }); cout << "the bigest box has a volume of " << moreBoxes.max().volume() << endl; return 0; }