一、类的定义
class 类名{
成员属性
构造函数
析构函数
成员函数
}
Person.h
#include <string>
#include <iostream>
using namespace std;
class Person {
int m_age;
string m_name;
Person();
Person(int age,string name);
~Person();
int getAge();
void setAge(int age);
string getName();
void setName(string name);
};
Person.cpp
#include "Person.h"
Person::Person() {}
Person::Person(int age, string name) :m_age(age), m_name(name) {}
Person::~Person() {
cout <<"析构函数调用" << endl;
}
int Person::getAge() {
return m_age;
}
void Person::setAge(int age) {
m_age = age;
}
string Person::getName() {
return m_name;
}
void Person::setName(string name) {
m_name = name;
}
- 如果要使用string类型的话,第一、需要添加#include <string>;第二、需要添加std的命名空间(using namespace std;)或者使用std::string
- 类里面的所有成员属性和函数默认都是私有的(private)
只需要调整访问权限为public即可。
二、类的实例对象创建
2.1、声明的时候,在栈中创建对象
Person person;
- 在栈中创建的对象会随着main函数执行的结束而销毁
2.2、使用new,在堆中创建对象
Person *person = new Person();
- 使用new创建的是一个指针
- main函数执行结束,person对象并没有调用析构函数,说明该对象还没有销毁,需要手动调用delete
2.3、使用malloc,在堆中创建对象
Person *person = (Person*)malloc(sizeof(Person));
- malloc创建的也是一个指针
- malloc创建对象的时候,没有调用构造方法,只是在堆中开辟了所需要大小的内存空间
- 需要调用free方法,来销毁创建的对象,释放内存
- 无论是使用malloc创建对象,以及使用free销毁对象,都不会调用类的构造函数和析构函数
三、类的成员属性的初始化
3.1、无构造函数的类
Person.h
#include <string>
#include <iostream>
using namespace std;
class Person {
int m_age;
string m_name;
public:
~Person();
int getAge();
void setAge(int age);
string getName();
void setName(string name);
};
Person.cpp
#include "Person.h"
Person::~Person() {
cout <<"析构函数调用" << endl;
}
int Person::getAge() {
return m_age;
}
void Person::setAge(int age) {
m_age = age;
}
string Person::getName() {
return m_name;
}
void Person::setName(string name) {
m_name = name;
}
- 对于无构造方法的类,只有只用new创建的对象的成员属性才会被初始化。
3.2、有构造函数的类
Person.h
#include <string>
#include <iostream>
using namespace std;
class Person {
int m_age;
string m_name;
public:
Person();
Person(int age,string name);
~Person();
int getAge();
void setAge(int age);
string getName();
void setName(string name);
};
Person.cpp
#include "Person.h"
Person::Person() {
cout << "构造方法调用" << endl;
}
Person::Person(int age, string name) :m_age(age), m_name(name) {}
Person::~Person() {
cout <<"析构函数调用" << endl;
}
int Person::getAge() {
return m_age;
}
void Person::setAge(int age) {
m_age = age;
}
string Person::getName() {
return m_name;
}
void Person::setName(string name) {
m_name = name;
}
- 如果类有构造函数,但是构造函数里面并没有对成员属性进行初始化的话,无论何种方式创建对象,对象的成员属性都不会被初始化
四、类的构造函数
4.1、定义
构造函数,是一种特殊的方法(没有返回值,方法名和类名相同)。 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值。
4.2、实现
Test.h
#pragma once
class Test
{
public:
int number_;
Test();
Test(int number);
};
Test.cpp
#include "Test.h"
Test::Test() {}
Test::Test(int number) {
number_ = number;
}
- 构造函数没有返回值
- 构造函数的函数名称与类名相同
- 构造函数可以重载
4.3、初始化列表
4.3.1、格式
标准构造函数格式:
Test::Test(int number) {
number_ = number;
}
初始化列表格式:
Test::Test(int number) :number_(number) {}
4.3.2、优势
- 传入参数可以是表达式
int a = 10;
Test* test = new Test(a+10);
- 传入参数可以是函数
#include <iostream>
#include "Test.h"
using namespace std;
int add(int a,int b);
int main() {
int a = 10;
Test* test = new Test(a+add(a,2));
cout << test->number_ << endl;
return 0;
}
int add(int a, int b) {
return a * b;
}
- 搭配默认参数,创建对象时,构造函数更灵活
PS:如果是采用声明和实现分离的方式定义类的话,初始化列表是写在头文件中的
Test.h
#pragma once
class Test
{
public:
int number_;
Test(int number=0) :number_(number) {};
};
#include <iostream>
#include "Test.h"
using namespace std;
int main() {
Test *test=new Test();
cout << test->number_ << endl;
Test *test1=new Test(18);
cout << test1->number_ << endl;
return 0;
}
4.4、补充
4.4.1、如果不创建构造函数,创建对象的时候会创建默认的构造函数吗?
Test.h
#pragma once
class Test
{
public:
int number_=0;
};
- 如果成员属性默认赋值,则会生成默认的构造函数,还会调用默认的构造函数
#pragma once
class Test
{
public:
int number_;
};
- 如果成员属性没有赋值,则不会生成默认的构造函数。
4.4.2、创建对象的时候,new test和new Test()有什么区别
- 如果类没有显示声明构造函数,都不会调用创建构造函数,但是带括号的会初始化成员属性
- 如果自定义构造函数,则都会调用构造方法,并且都不会初始化成员属性