类的定义、属性封装、只读属性
class Phone{
// 类成员默认是private struct 默认是public
public:
char name[20];// 属性
int type;
void sendMessage();// 成员函数
void callUp();
void playGame();
void setAge(int _age)// 属性的封装
{//处理
age = _age;
}
int getAge()
{
// 处理
return age;
}
int getColor()// 或者只能读
{
return color;
}
private:
int age;
int color;
protected:
int sex;
};
对象的实例与成员访问
int main(void)
{
// 栈中中定义
Phone phone;
phone.callUp();
// 堆中定义
Phone *myPhone = new Phone();
myPhone->setAge(20);
myPhone->getAge();
std::cout << myPhone->getAge()<< std::endl;
delete myPhone;
myPhone = NULL;
Phone *pphone = new Phone[20]();
for (int i = 0; i<20; i++) {
pphone[i].setAge(i);
}
for (int i = 0; i<20; i++) {
std::cout << pphone[i].getAge()<< std::endl;
}
return 0;
}
类内定义VS类外定义
class Car{
public:
void run(){};
void stop(){};
};
// 类外定义
class Phone{
public:
void run();
void stop();
};
void Phone::run(){
}
void Phone::stop(){
}
类外定义高级形式
.h文件写定义
.cpp写实现
命名规范
类名单词首字母大写
文件名同类名
函数名第二个单词首字母大写,由动词或动宾短语组成
数据成员以(m_类型)做前缀
int m_i float m_f string m_str
对象的存储结构
栈区、堆区、常量区、代码去、全局区
构造函数的特点
实例化对象时被自动调用
构造函数名与类名相同且没有返回值
如果没有自定义构造函数,系统提供默认构造函数
class Student
{
public:
Student(){};// 没有定义构造函数,系统默认会产生这这样一个构造函数、构造函数可以重载
Student(string name,int age =10)// 有参数的构造函数、也可以有默认值
{
m_strName = name;
m_iAge = age;
}
private:
string m_strName;
int m_iAge;
};
int main(void)
{
Student sut("jk",30);
Student *p = new Student();// 如果实现的带参数,没实现没参数的构造函数,这样会错误
}
初始化列表
class Taxi{
private:
const int m_iCount;
const int m_iColor;
public:
Taxi():m_iCount(10),m_iColor(20){// 初始化列表,给m_iCount赋初始值,也可以多个
}
};
int main(void)
{
Taxi taxi;
Taxi *p = new Taxi();
return 0;
}
int x = 1024;// 直接初始化
Taxi taxi1(taxi);// 复制初始化
拷贝构造函数
如果没有自定义的拷贝构造函数则系统自动生成
当对象直接初始化或复制初始化时自动调用拷贝构造函数
当自定义了拷贝构造函数则系统不再生成默认拷贝构造函数
class Taxi{
private:
const int m_iCount;
const int m_iColor;
public:
Taxi(const Taxi &taxi);// 自定义拷贝构造函数
Taxi():m_iCount(10),m_iColor(20){// 初始化列表,给m_iCount赋初始值,也可以多个
}
};
Taxi::Taxi(const Taxi &taxi):m_iCount(10),m_iColor(20)
{
cout<< "调用了拷贝构造函数" << endl;
}
int main(void)
{
Taxi taxi;
Taxi *p = new Taxi(); // 调用了无参数的默认构造函数
Taxi taxi2 = taxi; // 直接初始化 都掉用了拷贝构造函数
Taxi taxi1(taxi);// 复制初始化 都掉用了拷贝构造函数
return 0;
}
析构函数定义规则
析构函数名如:~类名
析构函数没有参数
析构函数没有返回值
析构函数不能重载
对象销毁时析构函数自动调用、无论栈中,还是堆在销毁的时候都会自动调用析狗函数
class Taxi{
private:
public:
~Taxi()
{
cout<< "调用了析构函数" << endl;
}
};
int main(void)
{
Taxi taxi;
Taxi *p = new Taxi();
delete p;
Taxi taxi2 = taxi;
Taxi taxi1(taxi);
// 调用了析构函数
// 调用了析构函数
// 调用了析构函数
// 调用了析构函数
return 0;
}
对象成员
#include <iostream>
using namespace std;
class Furniture
{
public:
Furniture(){
cout << "Furniture"<< endl;
}
Furniture(string name)
{
m_strName = name;
}
void setName(string name)
{
m_strName = name;
}
string getName()
{
return m_strName;
}
~Furniture()
{
cout << "~Furniture"<< endl;
}
private:
string m_strName;
};
class House
{
public:
House(string code,string furname):m_furBed(furname){
cout << "House(string code,string furname)"<< endl;
m_strCode = code;
}
House(string code)
{
cout << "House(string code)"<< endl;
//m_strCode = code;
//House::House(code,"");错误
new (this)House(code,"");
//在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存
}
Furniture &getFur()// 获取成员对象必须&
{
return m_furBed;
}
string getCode()
{
return m_strCode;
}
~House(){
cout << "~House"<< endl;
}
private:
string m_strCode;
Furniture m_furBed;
};
int main(void)
{
House *p = new House("1001");// 先调用Furniture构造函数 再调用House构造函数House析构造函数Furniture析构函数
//p->getFur().setName("yyyy");
cout << p->getCode() <<endl;
cout << p->getFur().getName() <<endl;
delete p;
p = NULL;
return 0;
}
对象实例化的过程
1)分配好内存(非静态数据成员是未初始化的)
2)调用构造函数(构造函数的本意就是初始化非静态数据成员)
分配内存(如果在存放的时候定义了初始化列表,就根据初始化列表将值直接放进相应的内存里 、然后执行构造函数里面的代码【内存二次写入】)
对象销毁过程
销毁的时候会自动调用析构函数,调用完后会自动把内存归还给系统。
什么样的情况需要自定义析构造函数
class Student
{
public:
Student(){
m_pName = new char[20];
}
~Student()
{
delete []m_pName;
}
private:
char *m_pName;//指针
};
当函数参数是一个对象,当我们在传参的时候,调用的是构造函数还是拷贝构造函数
拷贝构造函数,实参也是。