类声明
//定义类
class Human{
};//别忘记分号
//定义对象
Human fred;
类中的const
class C{
public:
//引用方式传参,又不改变传入的参数,最好用const。防止误写且编译器能优化
void setName(const String& n){name=n;}
//如果成员函数不需要改变对象的成员变量,成员函数最好标为const
int getAge()const{return age;}
//const表明谁也不能通过这个引用修改name的值。const返回只能赋值给const变量
const String& getName(){return name;}
private:
String name;
int age;
};
构造函数
//构造函数
//默认构造函数,带参构造函数
class Human{
private:
int age;
string name;
Human(){}//默认构造函数设置为私有,能确保对象被创建时必须使用共有带参构造函数正确初始化
public:
Human(string s,int n){name=s;age=n;}//带参构造函数
int& getAge(){return age;}
const string& getName()const{return name;}
};
//带参构造函数中重要的两类:拷贝构造函数,转型构造函数
//1.拷贝构造函数:是另一个对象的拷贝
Human(Human&);//单参数拷贝构造函数必须是引用
Human(const Human&);//或者这样
Human(Human& p, bool isMarried=false);//可以有多个参数,除了第一个,后边的必须都有默认值
//程序员不提供的话,系统会自动提供拷贝构造函数
Human alice("alice",12);
Human Lily(alice);//Lily拷贝了alice的内容
//需要手动提供的情况:如果对象内有指向动态存储空间的指针成员变量。
//自动拷贝后他们会指向同一块内存,一个对象修改这块空间会影响另一块。
//手动提供
Human(Human& p){
arr=0;
delete[] arr;
if(p.arr!=0){
arr=new string[size=p.size];
for(int i=0;i<size;i++){
arr[i]=p.arr[i];
}
}else{
arr=0;
size=0;
}
}
//2.转型构造函数:用于类型间的转换,只有一个参数
Human(const string&n){name=n;}//转型构造函数
void f(Human p);//某个函数期待Human类型的输入
//由于Human有string类型的转型构造函数,因此可以传入一个string变量,会自动构造一个Human
const成员变量初始化
//不能直接初始化,需要在构造函数添加初始化列表
class Human{
privete:
const int c;
int x;
public:
Human():c(333),x(121){};
};
析构函数
//没有参数,不能重载,所以每个类只有一个。
//没有提供的话编译器自动提供。
//和构造函数一样没有返回值,void也不行
//可以是虚函数,因为可以向上转型,所以可能需要用父类的析构函数但是要释放子类的空间,不用虚函数可能造成不能释放正确的内存大小,内存泄漏。
static(类数据成员/静态数据成员)
//同一个类的所有对象共享。包括成员变量和成员函数
//除了平常的访问方式,还多了 类名::静态成员数据 这种访问方式
//静态成员函数只能调用其他静态的成员变量或者静态成员函数
this关键字
class Human{
private:
int num;
public:
Human(int num){this->num=num;}//this 指本对象,此处用来this->num是成员变量num,后一个num是传入的参数
};
//this只有在非静态成员函数内才生效