C++类操作知识

1 类基础
一个类是一个用户自定义的类型,通常是一组成员构成,最常见的成员类别是数据成员和成员函数。成员函数可以定义初始化、拷贝、移动和析构(清理)等语义,对对象使用.操作来访问成员,对指针使用->来访问成员。一个类包含一个成员的名字空间,public成员提供类的接口,private成员提供实现的细节,struct是成员默认为public的class。

class X{
private:
int m;
public:
X(int i=0) :m{i} {}	//构造函数

int mf(int i)	//成员函数
{
int old=m;
m=i;
return old;
}
};

X var {7}int user(X var,X* ptr)
{
int x=var.mf(7)int y=var->mf(7)int z=var.m;		//错误,不能访问私有成员。
};

1.1 成员函数
struct结构下:

struct Date{
int d,m,y;
void init(int dd,int mm,int yy);		//初始化
void add_year(int n);			//增加n年
void add_month(int n);			//增加n月
void add_day(int n);			//增加n天
}

由于不同结构可能有同名成员函数,在定义成员函数时必须指定结构名:

void Date::init(int dd,int mm,int yy)
{
d=dd;
m=mm;
y=yy;
};

1.2 默认拷贝
Date d1=my_birthday;
Date d2 {my_birthday};
类似的,类对象也可以通过赋值操作拷贝.

void f(Date& d)
{
d=my_birthday;
}

默认拷贝语义是逐成员复制。

1.3 访问控制
标签public将类主体分为2部分,第一部分的名字是私有(private)的,它们只能被成员函数使用;第二部分是公有(public)的,构成类对象的公共接口。没有声明之前,类成员和成员函数默认是私有的,且非成员函数禁止使用私有成员。

1.4 class和struct区别
class X{…};根据定义,struct就是一个成员默认为公有的类,即struct S{ // };就是下面定义的简写

class S{ public /*...*/ }class Date1{
int d,m,y;		//默认私有
public:
Date1(int dd,int mm,int yy);
void add_year(int n);
};
struct Date2 {
private:
int d,m,y;		
public:
Date2(int dd,int mm,int yy);
void add_year(int n);
};

事实上,Date1和Date2是等价的,除了名字不一样外。C++并不要求在类定义中首先声明数据,实际上,将数据成员放在最后以强调提供公共用户接口的函数是很有意义的。

class Date3{
public:
Date3(int dd,int mm,int yy);
void add_year(int n);
private:
int d,m,y;
};

在一个类声明中可以多次使用访问说明符。

class Date4{
public:
Date4(int dd,int mm,int yy);
private:
int d,m,y;
public:
void add_year(int n);
};

1.5 构造函数
允许程序员声明一个函数,显式表明自己是专门完成对象初始化任务的。由于这种函数本质是构造一个给定类型的值,称为构造函数。构造函数的显著特征是与类具有相同的名字。

class Date1{
int d,m,y;		//默认私有
public:
Date1(int dd,int mm,int yy);	//构造函数
void add_year(int n);
//....
};
//构造函数初始化参数:
Date today=Date (23,6,1983);
Date xmas (25,3,1993);
Date today=Date {23,6,1983};
Date xmas {25,3,1993};

构造函数的重载规则与普通函数相同,只要构造函数的参数类型明显不同,编译器就能选择正确的版本使用。

1.6 explicit构造函数
我们可以指明构造函数不能用作隐式类型转换,如果构造函数的声明带有关键字explicit,则它只能用于初始化和显式类型转换。用=进行初始化可看作拷贝初始化,一般来说这种拷贝可能会被优化掉,而采取移动操作。省略=将会变为显式初始化,显式初始化又称直接初始化。

struct X{
explicit X();
explicit X(int,int);
};

X x1={};		//错误,隐式的;
X x2={1,2};	//错误,隐式的;

X x3 {};		//正确,显式的;
X x4 {1,2};	//正确,显式的;

int f(X);
int i1=f({});		//错误,隐式的;
int i2=f({1,2});		//错误,隐式的;

int i3 f({});			//正确,显式的;
int i4 f({1,2});		//正确,显式的;

1.7 类内函数定义
如果一个函数不仅在类中声明,还在类中定义,那么它就被当做内联函数处理。

class Date{
public:
void add_month(int n) {m+=n;};
//....
private:
int d,m,y;
};
等价于:
class Date{
public:
void add_month(int n) {m+=n;};
//....
private:
int d,m,y;
};

inline void Date::add_month(int n)
 {
m+=n;
};

1.8 可变性
const和非const对象都可以调用cosnt成员函数,而非const成员函数只能被非const对象调用,const函数不能修改其数据成员。例如:

void f(Date &d,const Date &cd)
{
int i=d.year();
d.add_year(1);

int j=cd.year();
cd.add_year(1);	//错误,不能改变const Date的值
}

我们可以将一个类成员定义为mutable,即使是在const对象中,也可以修改此成员。因此该函数即可用于const对象,也可以用于非const对象。

1.9 成员访问
通过对类X的对象使用.或者->操作来访问X的成员。

struct X{
void f();
int m;
}void X::f()
{
m=1;	//等价于this->m=1;
}

是类的一部分但不是某个类对象一部分的变量称为static成员,类似的,需要访问类成员而不需要通过特定对象调用的函数称为static成员函数。嵌套类能访问其所属类的成员,甚至是private成员,相反,一个类并没有任何特殊权限能访问其嵌入类的成员。

2 构造、清理、拷贝和移动

class X{
X(Sometype);		//普通构造函数;
X();				//默认构造函数;
X(const X&);		//拷贝构造函数;
X(X&& );			//移动构造函数;
X& operator=(const X&);		//拷贝赋值运算符;
X& operator=(X&&);		//拷贝赋值运算符;
~X();			//析构函数;
//...
}

2.1 构造函数和析构函数
与类同名的成员称为构造函数。构造函数的声明指出与参数列表,但未指出返回类型,类名不可用于此类内的普通成员函数、数据成员、成员类型等等。

class Vector{
public:
Vector(int s);
//...
};

某些类需要一个函数,在对象销毁时保证被调用,就像在对象创建时保证构造函数会被调用一样,这样的函数称为析构函数。析构函数不接受参数,且每一类只能有一个析构函数。

2.2基类和成员析构函数
构造函数调用其基类的构造函数,然后调用成员的构造函数,最后执行自身的函数体。析构函数执行自身的函数体,然后调用成员的析构函数,最后调用基类的析构函数。

2.3 调用构造函数和析构函数
2.4 virtual析构函数
析构函数可以声明为virtual,而且对含有虚函数的类通常这么执行。

2.5 static成员初始化
一个static类成员是静态分配,而不是每个类对象的一部分。一般来说,static成员声明充当类外定义的声明。但是在少数情况下,在类内声明中初始化static成员也是可能的,条件是static成员必须是整型或枚举类型的const,或者字面值类型的constexpr.

class Curious{
public:
static const int c1=7;		//正确;
static int c2=11;			//错误,非const;
const int c3=13;			//正确,但非static;
static const int c4=sqrt(9);	//错误,类内初始化器不是常量;
static const float c5=7.0;		//错误,类内初始化器不是整型(应该使用constexpr//而非const);
}

2.6 拷贝和移动
类拷贝操作两种方式:
默认构造函数:X()
拷贝构造函数:X (const X&)
拷贝赋值运算符: X& operator=(const X&)
移动构造函数:X (X &&)
移动赋值运算符: X& operator=(X &&)
析构函数:~X()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值