首页 > 其他 > 详细

cpp

时间:2021-07-03 22:18:10      阅读:35      评论:0      收藏:0      [点我收藏+]

4 类和对象

4.2 对象的初始化和清理

4.2.6 初始化列表

  • 作用: 初始化对象的属性
  • 为什么使用: 初始化发生在构造函数的语句之前, 若是使用构造函数内的语句赋值会浪费性能;
  • 语法: 构造函数():属性1(值1),属性2(值2)...{}
class Person 
{
    person(int a, int b, int c): m_a(a), m_b(b), m_c(c)
    {
        
    }
};
void test()
{
    Person person(10, 20, 30);
}

4.2.7 类对象作为类成员

c++中类的成员可以是另一个类的对象, 称为对象成员

对象成员先构造后析构

例如:

class A{};
class B
{
    A a;
};
#include <iostream>
using namespace std;
#include <string>
//手机类
class Phone
{
public:
    Phone(String pName): m_PName(pName){}
    String m_PName;
};
class Person
{
public:
    Person(string name, String pName): m_Name(name), m_Phone(pName){}
    String m_Name;
    String m_Phone;
};
void test(){
    Person p("张三", "手机");
}

4.28 静态成员

在成员变量和成员函数前加 static 关键字, 称为静态成员

访问方法: 静态成员可以使用对象访问, 也可以使用类名访问

静态成员也是有访问权限的

  • 静态成员变量
    • 多有对象共享同一份数据
    • 在编译阶段分布内存
    • 类内声明, 类外初始化
  • 静态成员函数
    • 所有对象共享一个函数
    • 静态成员函数只能访问静态成员变量
class Person
{
    public:
    static int m_A;
};

int Person::m_A = 100;
void test()
{
    Person p;
    //对象访问
    cout << p.m_A << endl;
    //类名访问
    cout << Person::m_A << endl;
}

4.3 c++对象模型和this指针

4.3.1 成员变量和成员函数分开存储

空对象的 sizeof 为 1, 若不是空的就是该多少多少

只有非静态成员变量属于类的对象上

4.3.2 this指针

this指针指向被调用的成员函数所属的对象

用途:

  1. 解决名称冲突

  2. 返回对象本身

    可以链式编程

    class Person
    {
        public:
        Person(int age):m_Age(age){}
        int m_Age;
        Person& PersonAddAge(Person &p)
        {
            m_Age += p.m_Age;
            return *this;
        }
    };
    void test()
    {
        Person p1(10):
        Person p2(10);
        p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
        cout << "p2.m_Age=" << p2.m_Age;
    }
    

4.3.3 空指针访问成员函数

空指针可以访问成员函数, 但容易引发空指针报错. 可以加

if (this==NULL){
    return;
}

来解决

4.3.4 const 修饰成员函数

常函数:

  • 成员函数加 const 后, 称这个函数为常函数

    void fun() const{}

  • 这个const修饰的是this指针, 让指针修饰的值也不可修改

  • 常函数内不可以修改成员属性

  • 成员属性声明时加关键字 mutable 后, 在常函数中仍可以修改

常对象:

  • 声明对象时加 const 称该函数为常对象
  • 常对象只能调用常函数

4.4 友元

目的: 让一个函数或者类访问另一个类中的私有成员

三种实现:

  • 全局函数做友元

    class Building
    {
        //友元声明
        friend void fun();
        private:
        int a;
    };
    void fun(Building building)
    {
    	cout << a << endl;
    }
    
  • 类做友元

    class Building
    {
        //友元声明
        friend class C;
        private:
        int a;
    };
    
  • 成员函数做友元

    class Building
    {
        //友元声明
        friend Class::fun();
        private:
        int a;
    };
    

4.5 运算符重载

对已有的运算符进行重新定义, 赋予其另一种功能, 以适应不同的数据类型

4.5.1 加号重载

  • 成员函数重载+号
Person operator+(Person &p)
{
    Person temp;
    temp m_A = this->m_A + p.m_A;
    temp m_B = this->m_B + p.m_B;
    return temp;
}
//使用
Person p3 = p1.operator+(p2);
//简化为
Person p3 = p1 + p2;
  • 全局函数重载+号
Person operator+(Person &p1, Person &p2)
{
    Person temp;
    temp m_A = p1.m_A + p2.m_A;
    temp m_B = p1.m_B + p2.m_B;
    return temp;
}
//使用
Person p3 = operator+(p1, p2);
//简化为
Person p3 = p1 + p2;

在操作数类型不同时, 运算符重载也可以发生函数重载

内置数据类型不能重载

4.5.2 左移运算符<<重载

通常不会用成员函数重载左移运算符, 只能用全局函数重载左移运算符

ostream &operator<< (ostream::&cout, Person &p)
{
    cout << "m_A = " << p.m_A << "; m_B = " << p.m_B;
    return cout;
}

若要访问私有变量就要把这个函数设为友元

4.5.3 递增运算符重载

类内:

class Myinteger
{
public:
    int m_Num;
    MyInteger():m_Num(0){}
    
	Myinteger& operator++()
	{
	    m_Num++;
	    return this;
	}
};

4.5.4 赋值运算符重载

编译器自己的拷贝是浅拷贝, 在析构时可能会重复释放报错

Person& operator=(Person &p)
{
    //编译器提供浅拷贝
    
    //判断堆区是否有属性存在, 若存在先释放
    if(m_Age != NULL)
    {
        delete m_Age;
        m_Age = NULL;
    }
    //深拷贝
    m_Age = new int(*p.m_Age);
    //返回自身
    return *this;
}

4.5.5 关系运算符重载

  • ==
  • !=
  • <
  • >

4.5.6 函数调用运算符重载

  • ()也可以重载
  • 重载后非常像函数调用, 称为仿函数
  • 仿函数没有固定写法, 非常灵活
//打印输出类
class MyPrint
{
    public:
    //重载函数调用运算符
    void operator()(String test)
    {
        cout << test << endl;
    }
};
void test()
{
    MyPrint myPrint;
    myPrint("hello world");
}
//加法类
class MyAdd
{
    public:
    int operator()(int num1, int num2)
    {
        return num1 + num2;	
    }
}
void test()
{
    MyAdd myAdd;
    int res = myAdd(100, 100);
    cout << "res = " << res << endl;
    
    //匿名函数对象
    cout << MyAdd(100, 100) << endl;
}

?

cpp

原文:https://www.cnblogs.com/karlshuyuan/p/14967433.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!