c++之隐式成员函数

c++自动提供下列成员函数:
 1.默认构造函数,如果没有定义构造函数
 2.复制构造函数,如果没有定义
 3.复制操作符,如果没有定义
 4.默认析构函数,如果没有定义
 5.地址操作符,如果没有定义
 我的一篇文章《c++之参数传递》中的StingBad案例就出现了:两次复制构造函数,导致析构函数被调用多了两次。
 一、默认构造函数
 1.如果用户没有提供任何构造函数,c++创建默认构造函数(没有任何参数,也不执行任何操作)
 2.用户定义构造函数,带参数的也可以是默认构造函数,只要参数都有默认值。
 二、复制构造函数(用户没有定义与赋值是相同的的构造函数,譬如用户定义类Sting(& p,int i)而没有定义Sting (& p),当用户用String s1("asdds")系统会复制(创建)构造函数Sting(&p))
 1.复制构造函数用于将一个对象复制到新创建的对象中,也就是说用于初始化过程中,二不是常规赋值中。类的复制构造函数原型通常如下:
 Clsaa _name (const Class_name &)
 譬如:
 StringBad (StringBad &)
 1.1复制构造函数何时会被调用呢?
 
 (1)新建一个对象并将其初始化为同类现有对象时,复制构造函数会被调用(当按值传递对象或函数返回对象时)系统会创建历史对象,都会使用复制构造函数。
 2.2复制构造函数的功能
 (1)默认的复制构造函数是逐个复制非静态成员,复制的是成员的值。
 3.3复制构造函数有什么缺点?
 (1)不管对象是如何创建的,析构函数都会在对象过期时调用(所以有一些对象被隐式复制构造函数创建,而没有任何提示,用户不知道对象的创建,如果有指针成员可能会对同一内存多次释放导致出错)
 <pre>
 如果类中包含有new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据而不是指针(深度复制),这样析构函数释放内存时就不会对同一内存多次释放
 
C++ 中,类型转换函数是一种类成员函数,它允许将一个类类型的对象自动转换为其他类型。这种转换函数通常以 `operator` 关键字开头,后跟目标类型,并且没有参数。类型转换函数的实现方非常直接,但需要注意其使用场景和潜在的副作用。 ### 基本语法 类型转换函数的定义格如下: ```cpp operator 目标类型() { // 返回目标类型的值 } ``` 例如,如果你有一个表示复数的类 `Complex`,并且希望将其实例转换为 `double` 类型(例如仅取实部),可以定义如下转换函数: ```cpp class Complex { private: double real_; double imag_; public: Complex(double real, double imag) : real_(real), imag_(imag) {} // 类型转换函数 operator double() { return real_; } }; ``` 这样,当需要将 `Complex` 对象用在期望 `double` 的上下文中时,编译器会自动调用这个转换函数[^3]。 ### 注意事项 1. **避免歧义**:如果类中定义了多个类型转换函数,可能会导致编译器在某些情况下无法确定使用哪一个转换函数,从而引发编译错误。因此,应谨慎定义多个转换函数。 2. **避免不必要的转换**:转换虽然方便,但过度使用可能导致代码难以理解和维护。为了提高代码的可读性和安全性,C++11 引入了 `explicit` 关键字,用于抑制转换。如果希望防止转换,可以在转换函数前加上 `explicit`: ```cpp explicit operator double() { return real_; } ``` 这样,在需要显转换时,必须使用 `static_cast<double>(complexObj)`,而不能自动转换[^5]。 3. **性能考虑**:转换可能引入额外的开销,尤其是在频繁调用的情况下。因此,在性能敏感的代码段中,应避免不必要的转换。 ### 示例代码 以下是一个完整的示例,展示了如何在 `Complex` 类中实现类型转换函数: ```cpp #include <iostream> class Complex { private: double real_; double imag_; public: Complex(double real, double imag) : real_(real), imag_(imag) {} // 类型转换函数 operator double() { return real_; } friend std::ostream& operator<<(std::ostream& os, const Complex& cp) { if (cp.real_) { os << cp.real_; } if (cp.imag_) { if (cp.real_) { os << '+'; } os << cp.imag_ << 'i'; } return os; } }; int main() { Complex c1(1.2, 3.5); double d = 1.8 + c1; // 自动调用转换函数 std::cout << "c1 = " << c1 << std::endl; std::cout << "d = " << d << std::endl; return 0; } ``` 在这个示例中,`Complex` 对象 `c1` 被转换为 `double` 类型,并与 `1.8` 相加。输出结果如下: ``` c1 = 1.2+3.5i d = 5.7 ``` ### 总结 类型转换函数是 C++ 中一种强大的工具,能够简化代码并提高可读性。然而,使用时需要小心,以避免歧义和不必要的性能开销。通过合理使用 `explicit` 关键字,可以更好地控制转换的行为,从而编写出更安全、更清晰的代码[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值