C++类和对象之相关特性解读

 更新时间:2025年05月22日 10:24:47   作者:zzh_zao  
这篇文章主要介绍了C++类和对象之相关特性,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一.类型转换

在C++中,类类型转换是指将一个类的对象转换为另一个类的对象,或者将一个类的对象转换为基本数据类型等。

C++提供了多种类型的转换机制,包括隐式类型转换和显式类型转换。

以下是关于C++类类型转换的详细介绍:

隐式类型转换

​构造函数实现的隐式转换

如果一个类的构造函数只有一个参数(除了可能的默认参数外),那么这个构造函数可以被用作隐式类型转换。例如:

class B {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
public:
    B(int x) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> /* ... */ }
};

这时,可以将int类型的值隐式转换为B类型的对象:

B b = 5; // 通过B的构造函数将5隐式转换为B对象

在类类型有多个参数时,可以使用{ xxx ,xxx },的形式来进行转换,不能使用(),因为()会计算出括号内最后一个表达式的值

类型转换运算符实现的隐式转换

类可以定义类型转换运算符,将类的对象隐式转换为其他类型。例如:

class A {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
public:
    operator int() const {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> return 10; }
};

这时,A类型的对象可以隐式转换为int类型:

A a;
int x = a; // 通过A的类型转换运算符将a隐式转换为int

这种隐式转换可能会导致一些意外的错误,因此可以通过在构造函数前加上explicit关键字来禁止这种隐式转换:

class B {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
public:
    explicit B(int x) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> /* ... */ }
};

这样,B b = 5;就会报错,而必须显式地调用构造函数:B b(5);。

类类型的对象之间也可以隐式转换,需要相应的构造函数⽀持

二.static成员

在C++中,static成员是类的一个重要特性,它与类本身相关联,而不是与类的某个具体对象相关联。这意味着static成员在类的所有对象之间是共享的。以下是对static成员的详细介绍:

static成员变量

定义与初始化

static成员变量是类的所有对象共享的变量。它在类的定义中声明,但需要在类的定义外进行初始化。 ⽤static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进⾏初始化。例如:

class MyClass {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
public:
    static int count; // 声明static成员变量
};

int MyClass::count = 0; // 初始化static成员变量

注意,static成员变量的初始化必须在类的定义外进行,且只能初始化一次。

访问方式

static成员变量可以通过类名或类的对象来访问,但推荐使用类名访问,以体现其与类的关系。例如:

MyClass::count = 10; // 通过类名访问
MyClass obj;
obj.count = 20; // 通过对象访问(不推荐,但合法)

无论通过类名还是对象访问,static成员变量都是同一个变量。

生命周期

static成员变量的生命周期从程序开始运行时初始化,到程序结束时销毁。它不依赖于类的对象的生命周期。

静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不⾛构造函数初始化列表.

static成员函数

定义与调用

static成员函数是与类相关联的函数,而不是与类的某个具体对象相关联。它不能访问非static成员变量和非static成员函数,因为这些成员需要对象的上下文。例如:

class MyClass {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
public:
    static void print() {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
        std::cout &lt;&lt; "Static function" &lt;&lt; std::endl;
    }
};
点击并拖拽以移动

static成员函数可以通过类名或类的对象来调用,但推荐使用类名调用。例如:

MyClass::print(); // 通过类名调用
MyClass obj;
obj.print(); // 通过对象调用(不推荐,但合法)

特点

  • static成员函数没有this指针,因为它不依赖于具体的对象。
  • 它可以访问类的static成员变量和其他static成员函数。
  • 静态成员也是类的成员,受public、protected、private访问限定符的限制。

应用场景

  • 常用于实现与类相关的工具函数,这些函数不需要访问类的对象的成员变量。
  • 例如,实现一个全局的计数器:
class MyClass {
public:
    static void incrementCount() { count++; }
    static int getCount() { return count; }
private:
    static int count;
};

int MyClass::count = 0;

int main() {
    MyClass::incrementCount();
    std::cout << MyClass::getCount() << std::endl; // 输出1
    return 0;
}

static成员的存储位置

  • static成员变量和static成员函数的存储位置通常在程序的全局数据区。它们在程序启动时分配内存,在程序结束时释放内存。
  • 与全局变量类似,static成员变量在全局数据区中有一个固定的地址,所有对象共享这个地址。
  • 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。

心得:

  • static成员变量和static成员函数是类的静态特性,它们与类本身相关联,而不是与类的对象相关联。
  • static成员变量需要在类的定义外初始化,并且可以通过类名或对象访问。
  • static修饰的成员函数,称之为静态成员函数 static成员函数没有this指针,只能访问类的static成员变量和其他static成员函数。
  • 静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
  • 静态成员函数中可以访问其他的静态成员,但是不能访问⾮静态的,因为没有this指针。
  • 突破类域就可以访问静态成员,可以通过类名::静态成员或者对象.静态成员 来访问静态成员变量和静态成员函数。

三.友元

在C++中,友元(Friend) 是一个非常重要的概念,它允许某些特定的函数或类访问另一个类的私有(private)和保护(protected)成员。

这在某些情况下非常有用,尤其是当你需要在类的封装性与功能需求之间找到平衡时。

友元函数

定义

  • 友元函数不是类的成员函数,但它可以访问类的私有和保护成员。
  • 友元函数需要在类的定义中使用friend关键字声明。

特点

  • 友元函数不是类的成员函数,因此它没有this指针。
  • 友元函数的定义可以位于类的定义内或定义外,但声明必须在类的定义中。
  • 友元函数可以访问类的所有成员(包括私有和保护成员)。
  • ⼀个函数可以是多个类的友元函数。

友元类

定义

  • 友元类是一个类,它的所有成员函数都可以访问另一个类的私有和保护成员。
  • 友元类需要在类的定义中使用friend关键字声明。例如:
class MyClass {
private:
    int privateData;

public:
    MyClass(int data) : privateData(data) {}
    friend class FriendClass; // 声明友元类
};

class FriendClass {
public:
    void printPrivateData(const MyClass& obj) {
        std::cout << "Private Data: " << obj.privateData << std::endl;
    }
};

在这个例子中,FriendClassMyClass的友元类,因此FriendClass的所有成员函数都可以访问MyClass的私有成员privateData

特点

  • 友元类的所有成员函数都可以访问被友元类声明的类的私有和保护成员。
  • 友元类的声明方式与友元函数类似,但声明的是整个类。

友元成员函数

定义

  • 友元成员函数是另一个类的成员函数,但它可以访问当前类的私有和保护成员。友元成员函数需要在类的定义中使用friend关键字声明,并指定所属类和函数名。

特点

  • 友元成员函数是另一个类的成员函数,但它可以访问当前类的私有和保护成员。
  • 友元成员函数的声明需要指定所属类和函数名。
  • 元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员。
  • 友元类的关系是单向的,不具有交换性,⽐如A类是B类的友元,但是B类不是A类的友元。
  • 友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元。

小结:

  • 友元函数:允许特定的非成员函数访问类的私有和保护成员。
  • 友元类:允许另一个类的所有成员函数访问当前类的私有和保护成员。
  • 友元成员函数:允许另一个类的特定成员函数访问当前类的私有和保护成员。
  • 使用注意事项:谨慎使用友元,尽量减少对类的内部结构的暴露,避免破坏封装性。友元破坏了类的封装性,因为它允许外部函数或类访问类的私有和保护成员。因此,应该谨慎使用友元,只在必要时才使用。

四.内部类

如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独⽴的类,跟定义在全局相⽐,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。

内部类默认是外部类的友元类。

内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使⽤,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地⽅都⽤不了。

内部类和外部类为平行关系,计算大小时不算内部类,内部类不算外部类的一部分,收访问限定符的限制

五.匿名对象

通常情况下,我们定义的是有名对象。

在C++中,匿名对象是指没有显式命名的对象。它们通常在需要临时使用某个类的对象时被创建,使用完毕后立即销毁。

匿名对象⽣命周期只在当前⼀⾏,⼀般临时定义⼀个对象当前⽤⼀下即可。

六.new

当使用动态内存分配(new)创建数组时,构造函数的调用机制与静态数组是相同的,但有一些额外的注意事项。

动态数组的构造函数调用
Sum* arr = new Sum[n];  // 动态创建长度为n的Sum数组

这行代码会:

  1. 在堆上分配足够存储n个Sum对象的内存
  2. 逐个调用每个元素的默认构造函数
  3. 返回指向第一个元素的指针
  4. 与静态数组一样,构造函数会被调用n次

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解如何利用C++实现一个反射类

    详解如何利用C++实现一个反射类

    这篇文章主要为大家详细介绍了如何利用C++实现一个反射类,文中的示例代码讲解详细,具有一定的参考价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • 关于Qt C++中connect的几种写法代码示例

    关于Qt C++中connect的几种写法代码示例

    这篇文章介绍了Qt中connect函数的不同编写方式,包括传统的槽函数写法、使用函数指针的写法、Lambda表达式以及使用QOverload选择重载信号的写法,每种写法都有其特点和适用场景,程序员应根据具体需求选择最合适的方式,需要的朋友可以参考下
    2024-11-11
  • 详解C++ const修饰符

    详解C++ const修饰符

    const 是 constant 的缩写,const可以帮我们避免无意之中的错误操作,本文给大家介绍C++ const修饰符的相关知识,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-05-05
  • win10中的dlib库安装过程

    win10中的dlib库安装过程

    这篇文章主要介绍了win10中dlib库的安装过程,本文通过实例图文介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C/C++实现crc码计算和校验

    C/C++实现crc码计算和校验

    循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术。本文主要介绍了C++实现crc码计算和校验的方法,需要的可以参考一下
    2023-03-03
  • 详解C++中String类模拟实现以及深拷贝浅拷贝

    详解C++中String类模拟实现以及深拷贝浅拷贝

    这篇文章主要介绍了详解C++中String类模拟实现以及深拷贝浅拷贝的相关资料,希望通过本文能帮助到大家,让大家实现这样的方法,需要的朋友可以参考下
    2017-10-10
  • C++ abs函数实际应用详解

    C++ abs函数实际应用详解

    本文我们来讲C++的abs函数以及实战运用,C++中的abs函数。在C++中使用abs函数要注意存在两种版本,一种是在stdlmb.h中定义的版本,另一个是在cmath头文件中定义的。夷实上在stdlib.h文件是C的函数,而cmath中的是C++版本
    2022-08-08
  • C++实现删除txt文件中指定内容的示例代码

    C++实现删除txt文件中指定内容的示例代码

    这篇文章主要介绍了C++实现删除txt文件中指定内容的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • 深入分析C++中类的大小

    深入分析C++中类的大小

    本篇文章深入分析了C++中类的大小问题。需要的朋友参考下
    2013-05-05
  • C++高精度计时的几种方法总结(测试函数运行时间)

    C++高精度计时的几种方法总结(测试函数运行时间)

    本文介绍了C++中常用的几种程序计时方法,包括clock()函数、GetTickCount()、QueryPerformanceCounter()以及C++11中的chrono库函数,这篇文章主要介绍了C++高精度计时的几种方法,需要的朋友可以参考下
    2024-09-09

最新评论