mooc程序设计与算法(三)C++面向对象程序设计 类和构造函数基础

注:本系列是 中国大学mooc(慕课) 程序设计与算法(三)C++面向对象程序设计 的课堂笔记和课后习题,每章一次,下面挂上网址:https://www.icourse163.org/course/PKU-1002029030 路漫漫其修远兮,吾将上下而求索(不知道能不能坚持更完系列)……..

一、类成员的可访问范围

  1. 私有成员(private):只能在成员函数内部访问,要访问一定要通过成员函数访问
  2. 公有成员(public):在任何地方都可以访问
  3. 保护成员(protected):以后再说(额。。。。好吧,ppt上是这样写的)
  4. 4.class中,为说明访问范围时,默认为私有,而struct中,默认为公有

二、 成员函数的重载及缺省

  1. 这里注意重载的二义性,比如下面这张图片:

这里写图片描述

三、构造函数

名字与类同名,不能有返回值,可以有参数,作用是初始化对象,如果没写,系统会生成一个默认的无参构造函数,一个类可以有多个构造函数

对象生成时自动调用

四、构造函数在数组中的使用

例子:

#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;
}

复制构造函数

这里写图片描述

复制构造函数起作用的三种情况

  1. 当用一个对象初始化同类的另一个对象时(如:c1、c2是对象,class c1(c2)或者class c1=c2)
  2. 某个函数的参数是该对象,这个函数被调用时
  3. 某个函数的返回值是该对象,则返回函数时,会调用。
    注:赋值语句不会调用复制构造函数(c1=c2),具体的情况看作业题

类型转换构造函数

  1. 目的:实现类型的自动转换
  2. 只有一个参数,而且不是复制构造函数,则看做是类型转换构造函数
  3. 当需要时,系统会调用类型转换构造函数,自动生成一个无名的临时对象。

例子:

#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无此问题。

猜你喜欢

转载自blog.csdn.net/abc15766228491/article/details/79862705