mooc程序设计与算法(三)第二周 类和构造函数基础
程序员文章站
2024-03-26 09:10:05
...
注:本系列是 中国大学mooc(慕课) 程序设计与算法(三)C++面向对象程序设计 的课堂笔记和课后习题,每章一次,下面挂上网址:https://www.icourse163.org/course/PKU-1002029030 路漫漫其修远兮,吾将上下而求索(不知道能不能坚持更完系列)……..
一、类成员的可访问范围
- 私有成员(private):只能在成员函数内部访问,要访问一定要通过成员函数访问
- 公有成员(public):在任何地方都可以访问
- 保护成员(protected):以后再说(额。。。。好吧,ppt上是这样写的)
- 4.class中,为说明访问范围时,默认为私有,而struct中,默认为公有
二、 成员函数的重载及缺省
- 这里注意重载的二义性,比如下面这张图片:
三、构造函数
名字与类同名,不能有返回值,可以有参数,作用是初始化对象,如果没写,系统会生成一个默认的无参构造函数,一个类可以有多个构造函数
对象生成时自动调用
四、构造函数在数组中的使用
例子:
#include <iostream>
using namespace std;
class CSample{
int x;
public:
CSample(){
cout<<"constructor 1 called"<<endl;
}
CSample(int n){
x = n;
cout<<"constructor 2 called"<<endl;
}
};
int main()
{
CSample array1[2];
cout<<"step1"<<endl;
CSample array2[2]={4,5};
cout<<"step2"<<endl;
CSample array3[2]={3};//注意这里,是一个有参构造函数,一个无参构造函数
cout<<"steps3"<<endl;
CSample * array4 = new CSample[
delete [] aray4;
return 0;
}
结果:
constructor 1 called
constructor 1 called
step1
constructor 2 called
constructor 2 called
step2
constructor 2 called
constructor 1 called
steps3
constructor 1 called
constructor 1 called
注意下面这个例子,是啥都没有输出的,就是说,这样定义指针数组,是没有调用构造函数的:
#include <iostream>
using namespace std;
class CSample{
int x;
public:
CSample(){
cout<<"constructor 1 called"<<endl;
}
CSample(int n){
x = n;
cout<<"constructor 2 called"<<endl;
}
};
int main()
{
CSample * array4 ={};
delete [] array4;
return 0;
}
复制构造函数
复制构造函数起作用的三种情况
- 当用一个对象初始化同类的另一个对象时(如:c1、c2是对象,class c1(c2)或者class c1=c2)
- 某个函数的参数是该对象,这个函数被调用时
- 某个函数的返回值是该对象,则返回函数时,会调用。
注:赋值语句不会调用复制构造函数(c1=c2),具体的情况看作业题
类型转换构造函数
- 目的:实现类型的自动转换
- 只有一个参数,而且不是复制构造函数,则看做是类型转换构造函数
- 当需要时,系统会调用类型转换构造函数,自动生成一个无名的临时对象。
例子:
#include <iostream>
using namespace std;
class Complex{
public:
double real,imag;
Complex(int i){
cout<<"i is:"<<i<<" inconstructor call"<<endl;
real = i;imag=0;
}
Complex(double r, double i)
{
real = r, imag=i;
}
};
int main(){
Complex c1(7,8);
Complex c2=12;
c1 = 9;
cout<<c1.real<<","<<c1.imag<<endl;
return 0;
}
结果:
i is:12 inconstructor call
i is:9 inconstructor call
9,0
析构函数
1、名字与类同名,前面加“~”,没有参数和返回值,如果不写,则系统会生成缺省的析构函数,关于析构函数什么时候被调用,看下面的例子:
#include <iostream>
using namespace std;
class Demo{
private:
int id;
public:
Demo(int i){
id=i;
cout<<"id="<<id<<" constructed"<<endl;
}
~Demo(){
cout<<"id="<<id<<" destructed"<<endl;
}
};
Demo d1(1);
void Func(){
static Demo d2(2);
Demo d3(3);
cout<<"func"<<endl;
}
int main()
{
Demo d4(4);
d4 = 6;
cout<<"main"<<endl;
{
Demo d5(5);
}
Func();
cout<<"main ends"<<endl;
return 0;
}
结果:
id=1 constructed
id=4 constructed
id=6 constructed
id=6 destructed
main
id=5 constructed
id=5 destructed
id=2 constructed
id=3 constructed
func
id=3 destructed
main ends
id=6 destructed
id=2 destructed
id=1 destructed
可以看到,最后的时候,是先析构了静态对象,再析构全局对象
关于复制构造函数,有时候,在dev在调用以对象作为参数的函数的时候,好像没有调用复制构造函数,其实是dev出于优化目的,未生成返回值临时对象而已,vs无此问题。