自定义数据类型
结构
特点:结构中的数据类型可以是除了所定义的结构类型以外的任何类型。
例子:
//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;
}