您的位置:首页 > 房产 > 建筑 > 苏州网页制作人才招聘_武汉江汉区疫情_网站关键词优化软件_网站seo关键词排名

苏州网页制作人才招聘_武汉江汉区疫情_网站关键词优化软件_网站seo关键词排名

2025/2/1 2:45:32 来源:https://blog.csdn.net/TechNomad/article/details/144543737  浏览:    关键词:苏州网页制作人才招聘_武汉江汉区疫情_网站关键词优化软件_网站seo关键词排名
苏州网页制作人才招聘_武汉江汉区疫情_网站关键词优化软件_网站seo关键词排名

文章目录

    • 一、C++中的构造函数
    • 二、C++中的析构函数
    • 三、两者的配合与注意事项
    • 四、C++中的静态成员变量
    • 五、C++中的静态成员函数
    • 六、C++中普通成员函数和静态成员函数的区别
    • 七、C++中的const成员变量
    • 八、C++中的const 成员函数
    • 九、C++中构造函数的初始化列表
    • 十、C++中的浅拷贝操作
    • 十一、C++中的深拷贝操作

一、C++中的构造函数

1.构造函数的定义和作用
构造函数是与类同名的特殊函数,在创建类的对象时自动调用,用于对对象进行初始化。

2.构造函数的特点

  • 与类同名:构造函数的名称必须与类名一致。
  • 无返回值:构造函数没有返回值(即使是 void 也不能写)。
  • 自动调用:在对象创建时自动调用,无需显式调用。
  • 支持重载:可以定义多个构造函数,参数列表不同即可(构成重载)。
  • 可以使用初始化列表:常用于初始化 const 数据成员或引用类型成员。

3.构造函数的类型
默认构造函数:无参数的构造函数。

class MyClass {
public:MyClass() { // 默认构造函数std::cout << "Default constructor called!" << std::endl;}
};
MyClass obj; // 自动调用默认构造函数

参数化构造函数:包含参数的构造函数。

class MyClass {
private:int x;
public:MyClass(int val) : x(val) { // 使用初始化列表std::cout << "Parameterized constructor called!" << std::endl;}
};
MyClass obj(10); // 调用参数化构造函数

拷贝构造函数:用于通过同类型对象初始化新对象。

class MyClass {
private:int x;
public:MyClass(int val) : x(val) {}MyClass(const MyClass& other) : x(other.x) { // 拷贝构造函数std::cout << "Copy constructor called!" << std::endl;}
};
MyClass obj1(10);
MyClass obj2 = obj1; // 调用拷贝构造函数

移动构造函数(C++11 引入):用于移动资源而不是复制资源,减少性能开销。

class MyClass {
private:int* data;
public:MyClass(int val) : data(new int(val)) {}MyClass(MyClass&& other) noexcept : data(other.data) { // 移动构造函数other.data = nullptr;std::cout << "Move constructor called!" << std::endl;}~MyClass() { delete data; }
};
MyClass obj1(10);
MyClass obj2 = std::move(obj1); // 调用移动构造函数

二、C++中的析构函数

1.析构函数的定义和作用
析构函数是与类同名并以 ~ 开头的特殊函数,在对象生命周期结束时自动调用,用于释放资源或执行清理操作。

2.析构函数的特点

  • 与类同名并以 ~ 开头。
  • 无参数、无返回值。
  • 自动调用:在对象超出作用域或被显式删除时自动调用。
  • 不能被重载:每个类只能有一个析构函数。
class MyClass {
public:MyClass() { std::cout << "Constructor called!" << std::endl; }~MyClass() { std::cout << "Destructor called!" << std::endl; }
};
int main() {MyClass obj; // 创建对象时调用构造函数
} // 作用域结束时,自动调用析构函数

3.析构函数的常见用途
释放动态内存:

class MyClass {
private:int* data;
public:MyClass(int val) : data(new int(val)) {}~MyClass() {delete data; // 释放动态内存std::cout << "Destructor called and memory freed!" << std::endl;}
};

三、两者的配合与注意事项

构造和析构的匹配:每次调用构造函数分配资源时,析构函数都应该负责释放资源(遵循 RAII 原则)。
虚析构函数:如果类包含虚函数,析构函数也应声明为 virtual,以确保通过基类指针删除派生类对象时,派生类的析构函数能被正确调用。

class Base {
public:virtual ~Base() { std::cout << "Base destructor called!" << std::endl; }
};
class Derived : public Base {
public:~Derived() { std::cout << "Derived destructor called!" << std::endl; }
};
Base* obj = new Derived();
delete obj; // 调用 Derived 和 Base 的析构函数

四、C++中的静态成员变量

静态成员变量是用 static 关键字声明的类成员变量。它是类的公共成员,在类的所有对象之间共享。
静态成员变量的特点:

  • 属于类,而非对象:静态成员变量只占用一份内存,不随对象的创建而分配,也不会随对象的销毁而释放。
  • 共享性:所有类的对象共享同一个静态成员变量。
  • 必须在类外定义并初始化(除非是 constexpr 静态变量)。
  • 存储周期:程序启动时分配内存,程序结束时释放。
  • 访问方式:可以通过对象或类名访问(推荐通过类名访问)。

类中静态成员变量的声明与定义:

#include <iostream>
class MyClass {
public:static int count; // 静态成员变量声明MyClass() {count++; // 每次创建对象时增加计数}
};// 静态成员变量必须在类外定义并初始化
int MyClass::count = 0;int main() {MyClass obj1, obj2, obj3;std::cout << "Total objects created: " << MyClass::count << std::endl;return 0;
}

C++11 引入的 constexpr 允许静态成员变量在类内定义,但必须是常量且编译时可确定值。

#include <iostream>
class MyClass {
public:static constexpr int maxObjects = 10; // 类内定义并初始化
};int main() {std::cout << "Maximum objects allowed: " << MyClass::maxObjects << std::endl;return 0;
}

五、C++中的静态成员函数

静态成员函数是用 static 修饰的类成员函数。它是类级别的行为,与具体对象无关。
静态成员函数的特点:

  • 不依赖对象:可以通过类名直接调用,无需实例化对象。
  • 只能访问静态成员:静态函数不能访问非静态成员变量或调用非静态成员函数。
  • 共享性:静态成员函数在类的所有对象之间共享。
  • 作用域限制:只能访问与类相关的静态数据或静态成员。

静态成员函数的基本用法:

#include <iostream>
class MyClass {
public:static int count; // 静态成员变量static void printCount() { // 静态成员函数std::cout << "Total objects created: " << count << std::endl;}
};int MyClass::count = 0;int main() {MyClass::count = 5; // 直接通过类名访问静态成员变量MyClass::printCount(); // 直接通过类名调用静态成员函数return 0;
}

静态成员函数访问静态变量:

#include <iostream>class MyClass {
private:static int count; // 静态成员变量
public:static void incrementCount() { count++; } // 修改静态成员变量static int getCount() { return count; }   // 获取静态成员变量
};// 静态成员变量定义和初始化
int MyClass::count = 0;int main() {MyClass::incrementCount(); // 调用静态函数MyClass::incrementCount();std::cout << "Count: " << MyClass::getCount() << std::endl;return 0;
}

六、C++中普通成员函数和静态成员函数的区别

在这里插入图片描述

七、C++中的const成员变量

const 成员变量的定义:

  • const 成员变量是类中的常量,其值一旦初始化后便不能更改。
  • const 成员变量通常需要在构造函数的初始化列表中进行初始化。

const 成员变量的特点:

  • 不可更改:一旦初始化,值不可修改。
  • 初始化方式:只能通过构造函数的初始化列表进行初始化,不能在构造函数的主体中赋值。
  • 作用范围:它的作用域与普通成员变量相同,但只能被读取。
#include <iostream>class MyClass {
private:const int value; // const 成员变量
public:// 使用初始化列表对 const 成员变量初始化MyClass(int v) : value(v) {}void printValue() const {std::cout << "Value: " << value << std::endl;}
};int main() {MyClass obj(42);obj.printValue(); // 输出 Value: 42// obj.value = 10; // 错误:无法修改 const 成员变量return 0;
}

八、C++中的const 成员函数

const 成员函数的定义:

  • const 成员函数是一个不会修改类中任何非静态成员变量的函数。
  • 在函数声明或定义后加 const 关键字来修饰该函数。

const 成员函数的特点:

  • 不能修改成员变量:在函数内不能更改任何非 mutable 的成员变量。
  • 只能调用其他 const 成员函数:在 const 成员函数中不能调用非 const 成员函数。
#include <iostream>class MyClass {
private:int value;
public:MyClass(int v) : value(v) {}int getValue() const { // const 成员函数return value;}void setValue(int v) { // 非 const 成员函数value = v;}
};int main() {const MyClass obj(10); // const 对象std::cout << "Value: " << obj.getValue() << std::endl; // 可以调用 const 成员函数// obj.setValue(20); // 错误:const 对象不能调用非 const 成员函数return 0;
}

普通对象也可以调用 const 成员函数,但 const 对象只能调用 const 成员函数。

int main() {MyClass obj(10); // 普通对象std::cout << "Value: " << obj.getValue() << std::endl; // 可以调用 const 成员函数obj.setValue(20); // 可以调用非 const 成员函数std::cout << "Updated Value: " << obj.getValue() << std::endl;return 0;
}

const 成员函数可以调用其他 const 成员函数,但不能调用非 const 成员函数。

#include <iostream>class MyClass {
private:int value;
public:MyClass(int v) : value(v) {}int getValue() const { return value; }void printValue() const {std::cout << "Value: " << getValue() << std::endl; // 调用另一个 const 成员函数}
};int main() {MyClass obj(42);obj.printValue();return 0;
}

如果类的成员变量用 mutable 修饰,则即使在 const 成员函数中也可以修改它。

#include <iostream>class MyClass {
private:mutable int mutableValue; // 可变成员变量
public:MyClass(int v) : mutableValue(v) {}void modifyValue() const {mutableValue++; // 在 const 成员函数中修改 mutable 成员std::cout << "Mutable Value: " << mutableValue << std::endl;}
};int main() {const MyClass obj(10);obj.modifyValue(); // 修改 mutable 成员变量return 0;
}

九、C++中构造函数的初始化列表

C++ 中,构造函数的初始化列表 是一种在对象构造时初始化类成员的方式。它提供了比在构造函数体内赋值更高效和灵活的初始化方式,特别是对于 const 成员、引用类型成员和基类的初始化至关重要。

1.初始化列表的语法
初始化列表紧跟构造函数的声明,使用冒号 : 开始,并列出成员变量或基类的初始化表达式。

class ClassName {
private:int member1;int member2;
public:// 构造函数使用初始化列表ClassName(int a, int b) : member1(a), member2(b) {// 构造函数体}
};

2.初始化列表的特点

效率高:

  • 初始化列表直接调用构造函数或赋值初始化成员变量,避免了默认构造和后续赋值的过程。
  • 对于复杂对象(如类类型成员),这种方式更高效。

适用性强:

  • 可以初始化const 成员变量。
  • 可以初始化引用类型成员变量。
  • 必须用于基类构造函数调用和成员对象的构造。

成员初始化顺序:

  • 成员的初始化顺序与它们在类中声明的顺序一致,而非在初始化列表中的顺序。
  • 建议按照声明顺序书写初始化列表,以避免潜在的错误和混淆。

3.普通成员变量的初始化

#include <iostream>class MyClass {
private:int x;int y;
public:// 使用初始化列表初始化成员变量MyClass(int a, int b) : x(a), y(b) {}void print() {std::cout << "x: " << x << ", y: " << y << std::endl;}
};int main() {MyClass obj(10, 20);obj.print(); // 输出: x: 10, y: 20return 0;
}

4.初始化 const 成员变量
const 成员变量必须在对象构造时完成初始化,且不能在构造函数体内赋值。

#include <iostream>
class MyClass {
private:const int value; // const 成员变量
public:MyClass(int v) : value(v) {} // 初始化列表初始化void print() {std::cout << "Value: " << value << std::endl;}
};int main() {MyClass obj(42);obj.print(); // 输出: Value: 42return 0;
}

5.初始化引用成员变量
引用类型的成员变量必须通过初始化列表进行初始化

#include <iostream>
class MyClass {
private:int& ref; // 引用类型成员
public:MyClass(int& r) : ref(r) {}void print() {std::cout << "Reference value: " << ref << std::endl;}
};int main() {int x = 100;MyClass obj(x);obj.print(); // 输出: Reference value: 100return 0;
}

6.初始化类类型成员变量
当类中包含其他类类型的成员时,这些成员的构造函数只能通过初始化列表调用。

#include <iostream>class Member {
private:int value;
public:Member(int v) : value(v) {std::cout << "Member constructed with value: " << value << std::endl;}
};class MyClass {
private:Member member; // 类类型成员
public:MyClass(int v) : member(v) {} // 初始化列表调用 Member 的构造函数
};int main() {MyClass obj(42);return 0;
}

输出:

Member constructed with value: 42

7.初始化基类和虚基类
派生类构造函数必须通过初始化列表调用基类的构造函数,尤其是基类没有默认构造函数时。

#include <iostream>class Base {
private:int value;
public:Base(int v) : value(v) {std::cout << "Base constructed with value: " << value << std::endl;}
};class Derived : public Base {
public:Derived(int v) : Base(v) { // 初始化列表调用基类构造函数std::cout << "Derived constructed" << std::endl;}
};int main() {Derived obj(42);return 0;
}

输出:

Base constructed with value: 42
Derived constructed

8.初始化列表的成员初始化顺序
成员变量的初始化顺序与它们在类中声明的顺序一致,而不是初始化列表的顺序。

#include <iostream>
class MyClass {
private:int a;int b;
public:MyClass(int x, int y) : b(y), a(x) { // 初始化顺序仍是 a -> bstd::cout << "a: " << a << ", b: " << b << std::endl;}
};int main() {MyClass obj(1, 2); // 输出: a: 1, b: 2return 0;
}

十、C++中的浅拷贝操作

浅拷贝(Shallow Copy)是C++中对象复制的一种方式,它复制对象中的非动态成员或指针成员的地址,而不是指针指向的实际内容。这种方式简单且高效,但可能带来潜在的问题,例如多个对象共享同一块内存区域时的资源冲突。

浅拷贝的特点:

  • 成员逐位复制: 浅拷贝直接将源对象的所有成员逐位复制到目标对象,包括指针的地址。
  • 效率高: 浅拷贝通常只需完成简单的内存操作,无需额外的深层处理。
  • 潜在问题: 由于共享了相同的动态内存,可能导致双重释放或数据不一致等问题。

浅拷贝一般由编译器自动生成的拷贝构造函数或赋值运算符完成,例如:

#include <iostream>
#include <cstring> // For std::strcpyclass ShallowCopyExample {
private:char* data;public:// 构造函数ShallowCopyExample(const char* initValue) {data = new char[strlen(initValue) + 1];std::strcpy(data, initValue);std::cout << "Constructor: Allocated memory for " << data << std::endl;}// 默认拷贝构造函数(浅拷贝)ShallowCopyExample(const ShallowCopyExample& other) = default;// 默认赋值运算符(浅拷贝)ShallowCopyExample& operator=(const ShallowCopyExample& other) = default;// 打印数据void print() const {std::cout << "Data: " << data << std::endl;}// 析构函数~ShallowCopyExample() {std::cout << "Destructor: Deleting memory for " << data << std::endl;delete[] data; // 如果多个对象共享同一块内存,这里会出错}
};int main() {ShallowCopyExample obj1("Hello");ShallowCopyExample obj2 = obj1; // 调用浅拷贝构造函数obj2.print();return 0; // 退出时,可能发生双重释放错误
}

输出示例:

Constructor: Allocated memory for Hello
Data: Hello
Destructor: Deleting memory for Hello
Destructor: Deleting memory for Hello // 可能导致崩溃

十一、C++中的深拷贝操作

深拷贝(Deep Copy)是C++中一种对象复制策略,其核心思想是复制对象中的数据内容,而不是直接共享指针或引用的内存地址。深拷贝的目的是确保每个对象都有自己独立的资源,避免资源冲突或双重释放等问题。

深拷贝的特点:

  • 独立性: 深拷贝为新对象分配新的内存并复制数据,因此新旧对象互不干扰。
  • 安全性: 深拷贝避免了浅拷贝中常见的资源管理问题,如双重释放或数据污染。
  • 代价: 深拷贝通常比浅拷贝消耗更多的资源和时间,因为它需要分配新的内存并复制数据。

深拷贝的实现:

#include <iostream>
#include <cstring> // For std::strcpyclass DeepCopyExample {
private:char* data; // 动态分配的资源public:// 构造函数DeepCopyExample(const char* initValue) {data = new char[strlen(initValue) + 1];std::strcpy(data, initValue);std::cout << "Constructor: Allocated memory for " << data << std::endl;}// 深拷贝构造函数DeepCopyExample(const DeepCopyExample& other) {data = new char[strlen(other.data) + 1];std::strcpy(data, other.data);std::cout << "Copy Constructor: Allocated new memory for " << data << std::endl;}// 深拷贝赋值运算符DeepCopyExample& operator=(const DeepCopyExample& other) {if (this != &other) { // 避免自我赋值delete[] data; // 释放已有内存data = new char[strlen(other.data) + 1];std::strcpy(data, other.data);std::cout << "Assignment Operator: Re-allocated memory for " << data << std::endl;}return *this;}// 打印数据void print() const {std::cout << "Data: " << data << std::endl;}// 析构函数~DeepCopyExample() {std::cout << "Destructor: Deleting memory for " << data << std::endl;delete[] data;}
};int main() {DeepCopyExample obj1("Hello");    // 构造对象DeepCopyExample obj2 = obj1;     // 调用拷贝构造函数obj2.print();DeepCopyExample obj3("World");obj3 = obj1;                     // 调用赋值运算符obj3.print();return 0;
}

输出结果:

Constructor: Allocated memory for Hello
Copy Constructor: Allocated new memory for Hello
Data: Hello
Constructor: Allocated memory for World
Assignment Operator: Re-allocated memory for Hello
Data: Hello
Destructor: Deleting memory for Hello
Destructor: Deleting memory for Hello
Destructor: Deleting memory for Hello

深拷贝与浅拷贝的比较
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com