C++学习笔记(7)

面向对象

1、基本特征

1.抽象

2.封装

3.继承

子类可以自动共享父类的数据结构和方法的机制,
单继承:子类只继承以父类的数据结构和方法。
多继承:子类可以继承多个父类的数据结构和方法(需小心二义性)。

4.多态

不同类对象调用相同的方法可以产生不同的结果

2、声明一个类

class class_name{
permission_lable:
member1;
permission_lable:
member2;
…….
};
permission_lable:权限标识符,可以是public、private、protected三个中的一个。
private(默认为该类型):私有成员,只有同一个类的其它成员或该类的“friend”类可以访问这些成员。
protected:保护成员,只有同一个类的其他成员或“friend”类或该类的子类可以访问这些成员
public:公有成员,任何可以看到该类的地方都可以访问这些成员。

3、类声明内外实现成员函数的区别

在类中直接编写的成员函数会被编译成内联函数,而在外部编写的函数会被编译成普通函数。
内联函数优点:加快运行效率
缺点:造成程序体积庞大。

4.const成员函数

加了该修饰后,函数体内的代码不能有任何修改类数据成员的代码。

int get_value() const{
    //value++;//编译会报错
    return value;
};

5、构造函数

特点:
1.命名必须和类名完全相同
2.功能主要用于在类的对象创建时定义初始化成员的状态。
3.没有返回值,也不能用void来修饰。
4.构造函数不能被直接调用,必须通过new运算符在创建对象或直接定义对象时才会被自动调用。
5.构造函数可以省略
6.如果把构造函数定义为私有,责无法创建对象。
7.有回滚效果
8.不能为虚函数

class stu{
private:
    int age;
    string name;
public:
    stu(int a, string n);
    int getAge(){ return age; }
    string getName(){ return name; }
};
stu::stu(int a, string n)
{
    age = a;
    name = n;
}
int _tmain(int argc, _TCHAR* argv[])
{
    //两种方法调用构造函数
    stu stu1(10,"liming");
    stu *stu2 = new stu(15,"xiaohong");
    cout << stu1.getName() << endl;
    cout << stu2->getName() << endl;
    return 0;
}

6、C++构造函数分类

1.默认构造函数
调用时不必给出实参,参数列表所有参数具有默认值

class stu{
private:
    int age;
    string name;
public:
    stu(int a=15, string n="xiaoming");//全部具有默认参数
    int getAge(){ return age; }
    string getName(){ return name; }
};
//默认参数不能重复定义
stu::stu(int a /*= 15*/, string n/* = "xiaoming"*/)
{
    age = a;
    name = n;
}

2.复制构造函数
对象间进行复制时会调用的构造函数。
如果未定义复制构造函数,编译器会自动生成一个复制构造函数,但是这个复制构造函数只能实现表层数值的复制,并不能实现堆空间数据的复制。如果类成员中存在指针,存在动态分配堆空间这种情况,那么编译器自动生成的复制构造函数就不合适了,需要用户自己定义。

class stu{
private:
    int age;
    string name;
public:
    stu(int a=15, string n="xiaoming");//全部具有默认参数
    stu(stu &s);//不带额外参数的复制构造函数
    int getAge(){ return age; }
    string getName(){ return name; }
};
stu::stu(stu &s){
    age = s.age;
    name = s.name;
    cout << "复制构造函数执行了"<<endl;
}
stu::stu(int a /*= 15*/, string n/* = "xiaoming"*/)
{
    age = a;
    name = n;
}
int _tmain(int argc, _TCHAR* argv[])
{
    stu stu1(10,"liming");
    stu stu2=stu1;//定义时赋值才会调用复制构造函数
    stu2 = stu1;//不会调用复制构造函数,有编译器默认实现的方法
    return 0;
}

3.深层复制构造函数
如何复制堆空间数据

class stu{
private:
    int age;
    string name;
    char *hometown;//定义了一个指针
public:
    stu(int a=15, string n="xiaoming",char* ht="hunan");//全部具有默认参数
    stu(stu &s);//不带额外参数的复制构造函数
    int getAge(){ return age; }
    string getName(){ return name; }
};
stu::stu(stu &s){//深层复制构造函数
    age = s.age;
    name = s.name;
    hometown = (char*)malloc(strlen(s.hometown));//分配堆空间
    strcpy(hometown, s.hometown);
    cout << "复制构造函数执行了"<<endl;
}
stu::stu(int a /*= 15*/, string n/* = "xiaoming"*/,char* ht)
{
    int leng;
    age = a;
    name = n;
    if (ht == NULL)
    {
        ht = "hunan";               
    }
    leng = strlen(ht);
    hometown = (char*)malloc(leng);
    strcpy(hometown, ht);
}
int _tmain(int argc, _TCHAR* argv[])
{
    stu stu1(10,"liming","beijing");
    stu stu2=stu1;//定义时赋值才会调用复制构造函数
    stu stu3(stu1);//同样调用复制构造函数
    return 0;
}

如果使用编译器默认的复制构造函数,那么只是进行hometown指针的复制,两个对象的hometown指针将指向同一内存区,当第一个对象析构后,第二个对象将会指向一个无效区域。

7、析构函数

8、构造函数初始化列表

class stu{
private:
    int age;
    string name;
public:
    stu(int a=15, string n="xiaoming");//全部具有默认参数
    int getAge(){ return age; }
    string getName(){ return name; }
};
//具有初始化参数列表的构造函数
stu::stu(int a , string n) :age(a), name(n)
{   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值