目录
必须使用初始化列表初始化的数据类型
- const成员
- 引用成员
- 无默认构造函数的内嵌对象成员
Student::Student(int age, string name, char sex) : m_age(age), m_name(name), m_sex(sex) { }
各种创建类对象的区别,调用函数的不同
创建类对象:===》调用构造函数
- 类名 对象名; ===》调用默认的构造函数 ===》调用无参构造函数 或者 调用带参数但是参数设有默认值的构造函数
- 类名 对象名(); //没有这种方式,编译器认为是函数的声明;
Student stu1();//编译器将类对象stu1的定义理解为一个函数的声明,该函数不接受参数并返回一个Student类型的对象.
- 类名 对象名(属性参数); ===》调用带参的构造函数
- 类名 对象名(已经构造的同一类型对象参数); ===》调用复制构造函数 称为:类对象的复制(对象创建同时赋初值)
- 类名 对象名 = 已经构造的同一类型对象; ===》调用复制构造函数 称为:类对象的复制(对象创建同时赋初值)
- 已经构造的对象A = 已经构造的同一类型对象B; ===》调用类的赋值操作符重载函数 称为:类对象的赋值(对象已经被创建)
复制构造函数和赋值操作符重载函数
类的复制构造函数执行的操作就是用同类型的对象给新创建的对象初始化的过程。
赋值操作符重载函数执行的操作是擦除已存在对象的内容,给这个对象赋新的值。
有动态内存的申请和释放,必须定义析构函数释放内存,必须定义复制构造函数和赋值操作符重载函数,来申请副本的动态内存,避免两个对象的指针成员操作同一块内存的情况。
自定义类string
#include <iostream>
#include <string.h>
using namespace std;
class MyString{
private:
char *m_str;
public:
//构造函数
MyString(const char *str = NULL){
cout << "构造函数"<< endl;
if (str == NULL){
m_str = new char[1];
m_str[0] = '\0';
}else{
m_str = new char[strlen(str) + 1];
strcpy(m_str, str);
}
}
//析构函数
~MyString(void){
cout << "析构函数"<< endl;
delete[] m_str;
m_str = NULL;
}
//复制构造
MyString(const MyString &other){
cout << "复制构造函数"<< endl;
m_str = new char[strlen(other.m_str) + 1];
strcpy(m_str, other.m_str);
}
//赋值运算符重载
MyString& operator = (const MyString& other){
cout << "赋值运算符重载"<< endl;
/****判断传入参数和自身(*this)是不是同一个实例,采用地址判断****/
if (&other.m_str == this){
return *this;
}
/*******释放原有的内存***********/
delete [] m_str;
m_str = NULL;
/*******************************/
m_str = new char[strlen(other.m_str) + 1];
strcpy(m_str, other.m_str);
return *this;
}
void getSet(char ch){
cout << "getSet"<< endl;
*m_str = ch;
return ;
}
//显示函数
void print(){
cout << "str=" << m_str << endl;
return ;
}
};
int main(void){
MyString str1("I am young");
str1.print();
MyString str2 = str1;
str2.getSet('d');
str2.print();
MyString str3("hello");
str3.print();
str3 = str1;
str3.print();
return 0;
}
成员函数指针的定义与使用
-
在c语言中,函数指针的主要用途是实现回调。
-
成员函数指针与普通函数指针在定义时有什么区别?
定义:需要声明所属的类,加上&
使用:加上*
#include <iostream>
using namespace std;
class Time{
public:
int hour;
int min;
int sec;
int get_hour(void){
return hour;
}
void display_time(void){
cout << "time:" << hour << ':' << min << ':' << sec <<endl;
}
};
int main(void){
Time t1;
t1.hour = 15;
t1.min = 53;
t1.sec = 33;
//成员函数指针的定义
int (Time::*p_get_hour)(void);//成员函数是类中的成员,要求声明成员函数所属的类
p_get_hour = &Time::get_hour;
//成员函数指针的定义
void (Time::*p_display_time)(void);
p_display_time = &Time::display_time;
//使用
cout<<(t1.*p_get_hour)()<<endl;
(t1.*p_display_time)();
return 0;
}
//运行输出
15
time:15:53:33
对象数组的初始化
学生对象数组进行初始化,用指针实现数组的遍历来输出学生的数据信息
#include <iostream>
#include <string.h>
using namespace std;
class Student{
private:
string number;
double score;
public:
Student(string number = "0", double score = 0):number(number), score(score){}
void print(void){
cout << "学号:" << number << " 成绩:" << score << endl;
}
};
int main(void){
//对象数组的初始化
Student stu[3] = {Student("1", 500), Student("2", 510), Student("3", 520)};
//用指针实现数组的遍历来输出学生的数据信息
Student *p = stu;
for (int i = 0; i < 3; i++){
(p + i)->print();
}
return 0;
}
类中内嵌对象数组成员,对数组成员进行初始化
#include <iostream>
using namespace std;
class A{
public:
int m_data;
A(int data = 0):m_data(data){}
};
class B{
private:
A a[5];
public:
//构造函数
B(A *a){
for (int i = 0; i < 5; i++){
this->a[i] = a[i];
}
}
void print(void){
for (int i = 0; i < 5; i++){
cout << a[i].m_data << endl;
}
return ;
}
};
int main(void){
A a[5] = {A(1), A(2), A(3), A(4), A(5)};
B b(a);
b.print();
return 0;
}