前向引用声明
类应该先声明,后使用
如果需要在某个类的声明之前,引用该类,则应进行前向引用声明(前置声明)。
前向引用声明只为程序引入一个标识符,但具体声明在其它地方。
eg:
class B; //前向引用声明
class A
{public:
void f(B &b);
};
class B
{public:
void g(A a);
};
前向引用声明注意事项
前向引用声明不是万能的。尽管使用了前向引用声明,但在提供一个完整的类声明(定义性声明)之前,不能声明该类的对象,也不能在内联成员函数中使用该类的对象。
class Fred;//前向引用声明
class Barney
{
Fred x; //错误:类Fred的声明尚不完善
}
class Fred
{
Barney y; //正确,类 Barney已经实现了
};
应该记住:当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。
class Fred;//前向引用声明
class Barney {
public:
void method()
{
x->yabba();//错误:在内联成员函数中使用该类的对象
}
private:
Fred* x;//正确,可以声明Fred类的对象指针或引用
};
class Fred {
public:
void yabba();
private:
Barney* y;
};
explicit仅用于关闭构造函数的转换功能
构造函数的副作用构造函数的原本作用就是将依照实参构建起类的对象来。
这个过程实际上完成了数据的类型转换——外界的数据变成了对象。这是构造函数的副作用。也就是说,构造函数每逢被调用,皆有两种解释。于是给使用它埋下了隐患。因为C++的旧的类型转换方式恰恰使用类型名(被转换数) 这样的形式。这也恰是构造函数显式调用的形式。那么,这样写究竟是构建对象还是类型转换?为了分离这种一式二义性,C++提供了关键字explicit,用于关闭构造函数的转换功能。
explicit仅用于关闭构造函数的转换功能。
例:
class two;
class one
{public: one( two &c) { } };
class two
{ public: two( const one & a) { } };
void func(twob) { }
{ }
void main()
{
one obj1;
func(obj1); //此时发生了二义
}
改造为:
class two;
class one
{ public: one( two &c) { } };
class two
{ public: explicit two( const one & a) { } };
void func(twob) { }
{ }
void main()
{
one obj1;
// func(obj1); //此时该语句错误
func( two(obj1) ); //必须显式使用转换
}
C++ 类的前向引用 和 explicit仅用于关闭构造函数的转换功能
最新推荐文章于 2021-12-23 22:49:21 发布