类型转换函数和类域
-
- [**Day6-3 类型转换函数和类域**](#Day6-3 类型转换函数和类域)
-
- [**1. 类型转换函数(Type Conversion Functions)**](#1. 类型转换函数(Type Conversion Functions))
-
- [**1.1 概述**](#1.1 概述)
- [**1.2 代码示例**](#1.2 代码示例)
- [**1.3 关键优化**](#1.3 关键优化)
- [**2. 类域(Class Scope)**](#2. 类域(Class Scope))
-
- [**2.1 作用域 vs 可见域**](#2.1 作用域 vs 可见域)
- [**2.2 代码示例**](#2.2 代码示例)
- [**2.3 关键优化**](#2.3 关键优化)
- [**3. 内部类(Nested Class)**](#3. 内部类(Nested Class))
-
- [**3.1 内部类的定义**](#3.1 内部类的定义)
- [**3.2 访问外部类的 `private` 成员**](#3.2 访问外部类的
private
成员) - [**3.3 静态内部类**](#3.3 静态内部类)
- [**4. 作用域运算符(Scope Resolution Operator `::`)**](#4. 作用域运算符(Scope Resolution Operator
::
)) -
- [**4.1 访问全局变量**](#4.1 访问全局变量)
- [**4.2 访问命名空间内的变量**](#4.2 访问命名空间内的变量)
- [**4.3 访问类的静态成员**](#4.3 访问类的静态成员)
- [**5. 类型转换运算符(Type Casting Operators)**](#5. 类型转换运算符(Type Casting Operators))
-
- [**5.1 `static_cast` 用法**](#5.1
static_cast
用法) - [**5.2 `dynamic_cast` 用法**](#5.2
dynamic_cast
用法) - [**5.3 `const_cast` 用法**](#5.3
const_cast
用法) - [**5.4 `reinterpret_cast` 用法**](#5.4
reinterpret_cast
用法)
- [**5.1 `static_cast` 用法**](#5.1
- [**6. 关键字 `explicit` 与类型转换**](#6. 关键字
explicit
与类型转换) -
- [**6.1 隐式转换**](#6.1 隐式转换)
- [**6.2 使用 `explicit` 禁止隐式转换**](#6.2 使用
explicit
禁止隐式转换)
- [**7. 总结**](#7. 总结)
Day6-3 类型转换函数和类域
1. 类型转换函数(Type Conversion Functions)
1.1 概述
类型转换函数用于将类的对象转换为其他类型,满足以下特点:
- 是类的成员函数,不能是友元函数或非成员函数。
- 没有参数列表 (即必须是
()
空参数)。 - 没有返回类型声明 ,即不能显式声明
void
或其他返回类型。 - 使用
return
语句返回目标类型的变量。
1.2 代码示例
cpp
#include <iostream>
using namespace std;
class Complex
{
friend std::ostream& operator<<(std::ostream& os, const Complex& rhs);
public:
Complex(int real = 0, int imag = 0)
: _real(real), _imag(imag)
{
cout << "Complex(int, int) 构造函数" << endl;
}
~Complex()
{
cout << "~Complex 析构函数" << endl;
}
void display() const
{
cout << _real << " + " << _imag << "i" << endl;
}
int getReal() const { return _real; }
int getImag() const { return _imag; }
private:
int _real;
int _imag;
};
// 重载输出运算符,使 Complex 可以被 cout 直接输出
std::ostream& operator<<(std::ostream& os, const Complex& rhs)
{
os << rhs._real << " + " << rhs._imag << "i";
return os;
}
class Point
{
friend std::ostream& operator<<(std::ostream& os, const Point& rhs);
public:
Point(int x = 0, int y = 0) : _x(x), _y(y)
{
cout << "Point(int, int) 构造函数" << endl;
}
// **类型转换函数**
operator int() const
{
cout << "operator int()" << endl;
return _x + _y;
}
operator double() const
{
cout << "operator double()" << endl;
return _y == 0 ? 0.0 : static_cast<double>(_x) / _y;
}
operator Complex() const
{
cout << "operator Complex()" << endl;
return Complex(_x, _y);
}
~Point()
{
cout << "~Point 析构函数" << endl;
}
// **类型转换构造函数**
explicit Point(const Complex& rhs)
: _x(rhs.getReal()), _y(rhs.getImag())
{
cout << "Point(const Complex&) 类型转换构造函数" << endl;
}
void print() const
{
cout << "(" << _x << ", " << _y << ")" << endl;
}
private:
int _x;
int _y;
};
// 重载输出运算符,使 Point 可以被 cout 直接输出
std::ostream& operator<<(std::ostream& os, const Point& rhs)
{
os << "(" << rhs._x << ", " << rhs._y << ")";
return os;
}
void testTypeConversion()
{
Point pt(3, 4);
cout << "Point pt: " << pt << endl;
int intValue = pt;
cout << "转换为 int: " << intValue << endl;
double doubleValue = pt;
cout << "转换为 double: " << doubleValue << endl;
Complex comValue = pt;
cout << "转换为 Complex: " << comValue << endl;
}
int main()
{
testTypeConversion();
return 0;
}
1.3 关键优化
✅ 类型转换构造函数 增加 explicit
,防止隐式转换导致潜在错误。
✅ 类型转换函数 添加 const
,保证 Point
的成员变量不会被修改。
✅ operator double()
处理 _y == 0
情况,避免除零异常。
✅ 优化 Complex
相关代码 ,消除 friend
冗余,提高可读性。
2. 类域(Class Scope)
2.1 作用域 vs 可见域
- 作用域(Scope) :指变量在代码中的可访问范围,影响变量的解析方式。
- 可见域(Visibility) :变量是否在当前上下文可见,受
private
、protected
、public
修饰符影响。 - 作用域 ≥ 可见域 ,如果没有命名冲突,二者相等。
2.2 代码示例
cpp
#include <iostream>
using namespace std;
int globalNumber = 50; // **全局作用域变量**
namespace ceshi
{
int namespaceNumber = 20; // **命名空间作用域**
class Test
{
public:
Test(int value = 100) : number(value) {}
void print(int number)
{
cout << "局部变量 number: " << number << endl;
cout << "成员变量 number: " << this->number << endl;
cout << "类作用域 number: " << Test::number << endl;
cout << "命名空间 ceshi::number: " << ceshi::namespaceNumber << endl;
cout << "全局变量 globalNumber: " << ::globalNumber << endl;
}
private:
int number; // **类成员变量**
};
} // namespace ceshi
void testScope()
{
int localValue = 3000;
ceshi::Test obj;
obj.print(localValue);
}
int main()
{
testScope();
return 0;
}
2.3 关键优化
✅ 清晰划分不同作用域 :全局作用域 ::
、命名空间 ceshi::
、类作用域 this->
和 Test::
。
✅ 增强 print()
方法输出格式 ,更直观理解变量的作用域。
✅ 消除不必要的析构函数 ,提升代码简洁性。
✅ 代码格式调整,增强可读性。
3. 内部类(Nested Class)
内部类(Nested Class)是指在一个类的定义内部再定义一个类。内部类在逻辑上属于外部类的一部分,但具有自己的作用域。
3.1 内部类的定义
cpp
#include <iostream>
using namespace std;
class Outer {
public:
class Inner { // 内部类
public:
void display() {
cout << "This is Inner class" << endl;
}
};
};
void test() {
Outer::Inner obj; // 创建内部类对象
obj.display();
}
int main() {
test();
return 0;
}
特点:
- 内部类的作用域受外部类的限制。
- 内部类的对象可以通过
外部类::内部类
的方式创建。 - 内部类可以访问外部类的
public
和protected
成员,但不能直接访问private
成员(除非使用friend
关键字)。
3.2 访问外部类的 private
成员
如果内部类需要访问外部类的 private
成员,可以将其声明为 friend
。
cpp
class Outer {
private:
int _data = 10;
public:
class Inner {
public:
void display(Outer& obj) {
cout << "Outer data: " << obj._data << endl;
}
};
};
void test2() {
Outer outerObj;
Outer::Inner innerObj;
innerObj.display(outerObj);
}
3.3 静态内部类
静态内部类不能访问外部类的非静态成员。
cpp
class Outer {
public:
static class StaticInner {
public:
void show() {
cout << "This is a static inner class" << endl;
}
};
};
void test3() {
Outer::StaticInner obj;
obj.show();
}
4. 作用域运算符(Scope Resolution Operator ::
)
作用域运算符 ::
用于指定变量、函数或类所属的作用域,主要应用如下:
4.1 访问全局变量
cpp
#include <iostream>
using namespace std;
int number = 100;
void test() {
int number = 50;
cout << "Local number: " << number << endl;
cout << "Global number: " << ::number << endl;
}
4.2 访问命名空间内的变量
cpp
namespace A {
int value = 10;
}
namespace B {
int value = 20;
}
void test2() {
cout << "A::value = " << A::value << endl;
cout << "B::value = " << B::value << endl;
}
4.3 访问类的静态成员
cpp
class Demo {
public:
static int data;
};
int Demo::data = 50;
void test3() {
cout << "Static data: " << Demo::data << endl;
}
5. 类型转换运算符(Type Casting Operators)
C++ 提供了四种类型转换运算符:
static_cast
:用于基本类型之间的转换。dynamic_cast
:用于多态类型的安全转换。const_cast
:用于去除const
或volatile
修饰符。reinterpret_cast
:用于不同类型指针之间的转换。
5.1 static_cast
用法
cpp
void test_static_cast() {
double num = 10.5;
int intNum = static_cast<int>(num);
cout << "Converted value: " << intNum << endl;
}
5.2 dynamic_cast
用法
cpp
class Base {
public:
virtual void show() {}
};
class Derived : public Base {
public:
void show() {
cout << "Derived class" << endl;
}
};
void test_dynamic_cast() {
Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
derivedPtr->show();
}
delete basePtr;
}
5.3 const_cast
用法
cpp
void test_const_cast() {
const int num = 42;
int* ptr = const_cast<int*>(&num);
*ptr = 10;
cout << "Modified value: " << *ptr << endl;
}
5.4 reinterpret_cast
用法
cpp
void test_reinterpret_cast() {
int num = 65;
char* ch = reinterpret_cast<char*>(&num);
cout << "Reinterpreted value: " << *ch << endl;
}
6. 关键字 explicit
与类型转换
默认情况下,C++ 允许构造函数进行隐式类型转换,但 explicit
关键字可以禁止这种行为。
6.1 隐式转换
cpp
class Demo {
public:
Demo(int x) { cout << "Demo(int)" << endl; }
};
void test_implicit_conversion() {
Demo obj = 10; // 隐式调用 Demo(int)
}
6.2 使用 explicit
禁止隐式转换
cpp
class Demo {
public:
explicit Demo(int x) { cout << "Demo(int)" << endl; }
};
void test_explicit() {
// Demo obj = 10; // 错误!隐式转换被禁止
Demo obj(10); // 正确
}
7. 总结
- 内部类 是定义在另一个类内部的类,具有自己的作用域,并且可以是
static
。 - 作用域运算符
::
用于访问不同作用域的变量或函数。 - 类型转换运算符 提供更安全、可控的转换方式。
explicit
关键字 可以防止构造函数的隐式转换。