c++特殊成员之const与static
特殊成员const
1.const数据成员
1.1 只能采用初始化参数列表的方式进行初始化
初始化参数列表:
构造函数名(参数1,参数2…):成员1(参数1),成员2(参数2)…{}
1.2 构造函数必须要初始化常数据成员
#include<iostream>
using namespace std;
class BOY
{
public:
//第一个BOY进行报错
BOY(int age):age(age){}
BOY(int age,const int num):age(age),num(num){}
public:
void print()
{
cout << "普通函数";
}
public:
int age;
const int num;
};
int main()
{
BOY boy(5);
boy.print();
return 0;
}
这就是因为没有初始化常数据成员
注意问题:
如果数据成员是如下这样的:
const string name;
构造函数我们不把name初始化,写出来也没什么事?这是为什么呢?
因为它调用了string默认的构造函数
实际上这里是个类的组合问题,类的组合就是:
以一个类的对象作为数据成员
闲聊:(这里值得回想的是,继承中子类构造函数的写法。除了要初始本类数据,还需要调用父类构造函数初始化继承下来的属性。
但是你子类没有写出来的时候,它实际上调用了父类那个无参的构造函数。这里只是想到了,随手写一下,与上面关系也不太大)
这里我们再写一个class MM来证明一下并且看一看测试结果:
#include<iostream>
#include<string.h>
using namespace std;
class MM
{
public:
MM( )
{
cout << "默认构造"<<endl;
}
};
class BOY
{
public:
//这里没写是没有报错的,当然也可以像下面一样写出来
BOY(int age,const int num):age(age),num(num){}
BOY(int age,const int num,const string name):age(age),num(num),name(name){}
public:
void print()
{
age = 100;
cout <<age<< "\t普通函数\t"<<num<<"\t"<<name.c_str()<<endl;
}
public:
mutable int age;
const int num;
const string name;
const MM mm;
};
int main()
{
BOY boy1(5,23);
boy1.print();
BOY boy2(3, 23, "忽儿嘿哟蚂蚱黑");
boy2.print();
return 0;
}
可以看到,两个对象都输出了,默认构造,几个字。
2.const成员函数
2.1 写法:const放在函数后面,一般写法:
类型名 函数名 (参数表) const
2.2 可以使用数据成员,但是不能修改
2.3 常成员函数可以和普通函数共存
3.const对象
定义常对象的一般形式为:
类名 const 对象名[(实参表)];
或者:
const 类名 对象名[(实参表)];
注意点:
3.1 常对象只能调用常成员函数,常成员函数是常对象对外的唯一接口。
不能调用普通成员函数,是防止普通成员函数修改数据。
非要修改某个值的时候(比如类中有一个计数count),应该对该数据成员声明为:mutable (可变的)
mutable int age;
3.2 普通对象优先调用普通函数
#include<iostream>
using namespace std;
class BOY
{
public:
BOY(int age,const int num):age(age),num(num){}
public:
void print()
{
age = 100;
cout <<age<< "\t普通函数\t"<<num<<endl;
}
void print()const
{
cout << age<<"\t常成员函数\t"<<num<<endl;
}
public:
int age;
const int num;
};
int main()
{
BOY boy1(5,23);
boy1.print();
const BOY boy2(5, 23);
boy2.print();
return 0;
}
运行结果:
特殊成员static
1 static数据成员:使用static修饰的数据成员
1.1 静态数据成员必须类外初始化,类外不需要static,需要类名前缀。
1.2 静态数据成员不属于对象,属于类,它的访问可以不需要对象。注意说的是可以不需要。
1.3 依旧受类名和权限限定词限定。
先来个报错的:
原因:受权限限定,改为public就可以啦
static数据成员能够记录上一次的执行结果,
2.static成员函数
1.静态函数在类外实现不需要static
2.静态函数不属于对象,访问可以不需要对象(当然也可以需要)
3.属于类,故而受权限限定词限定
4.静态函数调用要用类名
#include<iostream>
using namespace std;
class BOY
{
public:
BOY(){
count++;
}
static void print1()
{
cout << count << endl;
}
static void print2();
public:
static int count;
};
int BOY::count = 0;
void BOY::print2()
{
cout << count << endl;
}
int main()
{
cout << BOY::count << endl;
BOY boy1;
//可以不需要对象
BOY::print1();
BOY boy2;
boy2.print2();
cout << BOY::count << endl;
return 0;
}
运行结果:
注意点:
静态数据成员的访问可以不需要对象。
静态成员函数访问静态数据成员时没有任何问题。
但是静态成员函数访问非静态数据成员时需要指明对象。
#include<iostream>
#include<string>
using namespace std;
class BOY
{
public:
BOY(string name):name(name){}
static void print1()
{
BOY *pBoy = new BOY("pBoy");
cout << pBoy->name << endl;
}
static void print2(BOY boy);
static void print3(BOY * pboy);
public:
string name;
};
void BOY::print2(BOY boy)
{
cout << boy.name << endl;
}
void BOY::print3(BOY * pboy)
{
cout << pboy->name << endl;
}
int main()
{
BOY boy("男孩");
// 在静态函数中产生对象
BOY::print1();
// 静态函数以对象为参数
BOY::print2(boy);
// 静态成员函数以对象指针为参数
BOY::print3(&boy);
boy.print1();
boy.print2(boy);
boy.print3(&boy);
return 0;
}