C++ | 期末冲刺版①

文章讲述了C++中的动态内存管理,包括new运算符的用法以及delete的匹配使用。强调了函数返回值不应为局部变量引用,介绍了占位参数的规则和默认参数的使用限制。同时,文章讨论了类和对象的概念,封装的原则,以及如何将类拆分成头文件和实现文件。接着,详细讲解了构造函数、析构函数、拷贝构造函数,特别是深拷贝和浅拷贝的区别及其重要性。最后,提到了静态成员的特性,包括静态成员变量和函数的使用。
摘要由CSDN通过智能技术生成

目录

new 的使用

占位参数

做函数的返回值注意:不要返回局部变量引用

类和对象

封装

将一个类拆分成两个文件

point.h(写类的框架,写函数声明)

point.cpp

构造和析构

拷贝构造函数

 有参和无参

深拷贝与浅拷贝

初识化列表

静态成员


new 的使用

int *p=new int(10);

int *array=new int[10];

delete p;

delete[ ] array;


占位参数

注意事项:如果某个位置已经有了默认参数,那么从这个位置往后都要有默认参数

//从b开始往后一的参数都有默认参数
int fun2(int a,int b= 10;int c =20)
{
    
}

如果函数的声明有默认参数,函数的实现就不能有默认参数了。 

声明和实现只能有一个有默认参数。


做函数的返回值
注意:不要返回局部变量引用

用法:函数调用作为左值

#include<iostream>
using namespace std;
int& test1()
{
    int a = 10;//栈区
    return a;
}
int& test2()
{
    static int b = 20;//静态变量存放在全局区,全局区的数据在程序结束后系统释放
    return b;
}
int main(void)
{
    int& ret = test1();
    int& ret2 = test2();
    cout << ret2 << endl; 
    //作为左值
    test2() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
    cout << ret2 << endl;
    cout << ret << endl;//第一次结果正确是因为编译器做了保留
    cout << ret;//第二次结果错误是因为a的内存已经释放
    return 0;
}


类和对象

class

{

};//后面有个分号,忘记了你就完蛋了!

封装


  

//成员函数判断是否相等(一个参数)
	 bool issamebyClass(Cube &c)
	 {																	
		 if (C_H== c.geth() && C_L == c.getl() && C_W == c.getw())
		 {
			 return true;
		 }
		 return false;
	 }
//全局函数(两个参数)
bool issame(Cube &c1, Cube &c2)
{
	if (c1.geth() == c2.geth() && c1.getl() == c2.getl() && c1.getw() == c2.getw())
	{
		return true;
	}
	return false;
}

将一个类拆分成两个文件

point.h(写类的框架,写函数声明)

#pragma once
#include<iostream>
using namespace std;
class Point
{
public:
    void setx(int x);
    int getx();
    void sety(int y);
    int gety();
private:
    int c_x;
    int c_y;
};


point.cpp

#include"point.h"
//Point::告诉编译器这是Point作用域下面的一个成员函数
void Point::setx(int x)
{
    c_x = x;
}
int Point::getx()
{
    return c_x;
}
void Point::sety(int y)
{
    Point::c_y = y;
}
int Point::gety()
{
    return c_y;
}

构造和析构

Person p;//默认构造函数调用
	/*注意:使用默认构造函数的时候,不要加(),编译器会认为这是一个函数的声明
	例如:Person p1();不会认为在创建对象*/
	Person p2(10);//有参构造函数调用
	Person p3(p2);//拷贝构造函数调用
	cout << "p2的年龄为" << p2.age << endl;
	cout << "p3的年龄为" << p3.age << endl;


拷贝构造函数

Person(const Person& p)
	{
		cout << "Person的拷贝构造函数调用" << endl;
		m_Age = p.m_Age;
	}

 有参和无参

总结

用户提供了有参,编译器不会提供无参,但会提供拷贝;

用户提供了拷贝,编译器什么构造函数都不会提供。


深拷贝与浅拷贝


深浅拷贝是面试的一个经典的问题,也是常见的一个坑。

浅拷贝:简单的赋值拷贝操作。

深拷贝:在堆区中重新申请空间,进行拷贝操作。

浅拷贝带来的问题——内存重复释放

#include<iostream>
using namespace std;
//深拷贝与浅拷贝问题
class Person
{
public:
    Person()
    {
        cout << "Person的默认构造函数调用" << endl;
    }
    Person(int age,int height)
    {
        m_Height = new int(height);
        m_Age = age;
        cout << "Person的有参构造函数调用" << endl;
    }
    Person(const Person& p)
    {
        cout << "Person的拷贝构造函数调用" << endl;
        m_Age = p.m_Age;
        m_Height = p.m_Height;编译器默认实现的就是这行代码
        
    }
    ~Person()
    {
        //将堆区开辟的数据进行释放
        if (m_Height !=NULL)
        {
            delete m_Height;
            m_Height = NULL;
        }
        cout << "Person的析构构造函数调用" << endl;
    }
 
    int m_Age;
    int* m_Height;//为什么要用指针——要把身高开辟到堆区
};
void test()
{
    Person p1(18,166);
    cout << p1.m_Age<<"\t" << *p1.m_Height << endl;
    Person p2(p1);
    cout << p2.m_Age<<"\t" <<*p2.m_Height<< endl;
}
int main(void)
{
    test();
    system("pause");
    return 0;

}


浅拷贝的这个问题需要用深拷贝来解决

重新在堆区找一块内存来存放他。

自己实现拷贝构造函数来解决浅拷贝带来的问题

解决:

深拷贝——手动创建拷贝构造函数。

Person(const Person& p)
{
    cout << "Person的拷贝构造函数调用" << endl;
    m_Age = p.m_Age;
    //m_Height = p.m_Height;编译器默认实现的就是这行代码
    //深拷贝操作
    m_Height = new int(*p.m_Height);
}



初识化列表

作用

C++提供了初始化列表语法,用来初始化对象。

语法

构造函数():属性1(值1),属性2(值2)…{}

Person():age(1),height(160){}//没有分号


类对象作为类成员 

当其他类的对象作为本类的成员时,构造时先构造其他类的对象,再构造自身。

析构呢?与构造函数相反。

自身的析构函数先进行,之后其它类再进行。

class Person{

Phone a;

};

 


静态成员

静态成员就是在成员变量和成员函数前面加上关键字啊static,称为静态成员。

静态成员分为

  • 静态成员变量
    • 所有对象共享同一份数据
    • 在编译阶段分配内存
    • 类内声明,类外初始化
  • 静态成员函数
    • 所有成员共享同一个函数
    • 静态成员函数只能访问静态成员变量
    • #include<iostream>
      using namespace std;
      class Person
      {
      public:
          //静态成员函数
          static void func()
          {
              age = 100;//静态的成员函数可以访问静态的成员变量,不可以访问非静态的成员变量
              //无法区分到底是哪个对象的成员变量
              cout << "static void func调用" << endl;
          }
          static int age;
          //静态成员函数也是有访问权限的
      private:
          static void func()
          {
      
          }
      };
      void test01()
      {
          //两种访问方式
          //通过对象访问
          Person p;
          p.func();
          //通过类名也可以访问
          Person::func();
          //Person::func2();类外访问不到私有的静态成员函数
      }
      int main(void)
      {
          test01();
          system("pause");
          return 0;
      }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值