一、什么是不完整类型
不完整类型是指在定义的时候并没有被完全定义的类型,如结构体或类的声明但未定义、数组大小未确定等,或是其定义在当前作用域之后。
例如:
struct Node;
void func(Node* node);
这里的结构体Node就是一个不完整类型。
二、为什么不允许使用不完整类型
在许多编程语言中,都有允许使用不完整类型的机制,但在c++中不允许使用。这是因为c++语言设计的时候,为了保证类型的安全性和编译器的可靠性,规定了不完整类型不能使用的规则。
1. 无法分配内存
对于不完整类型,在编译器还没有完全建立其类型的信息时,无法准确的确定该类型所需分配的内存大小,因此也就无法分配内存。
struct Node;
void func() {
Node* node = new Node; // 编译器无法确定Node类型的内存大小,因此会报错
}
2. 无法使用该类型的成员变量和成员函数
对于不完整类型,由于其类型的信息还没有完全确定下来,因此编译器也无法获得该类型中的成员变量和成员函数的信息,因此无法使用。
struct Node;
void func(Node* node) {
int value = node->val; // 编译器无法确定Node类型中是否有val成员变量,因此会报错
}
3. 暂时无法确定类型的相互依赖问题
有时候两个类型在定义中相互依赖,但在其中一个类的定义中,需要引用另一个类,此时如果另一个类还没有被完全定义,则引用会出现问题。
class A {
public:
void func(B& b); // 在A类定义中引用B类
};
class B {
public:
void func(A& a);
};
void A::func(B& b) {
b.func(*this); // 这里需要使用A类的信息,但此时B类还未被完全定义,因此会报错
}
三、如何避免使用不完整类型
为了避免使用不完整类型造成的编译问题,可以采取以下方法。
1. 完全定义类型
最好的方法是完全定义类型,这样就可以避免出现不完整类型的问题。
struct Node {
int val;
};
2. 通过指针或引用的方式传递
在函数参数中,可以通过指针或引用的方式传递不完整类型,这样可以避免类型的内存分配和成员变量的访问问题。
struct Node;
void func(Node* node);
void func(Node& node);
3. 使用前先定义
在C++中,如果一个类只有在以后的时刻才会被使用,可以先进行声明,之后再进行定义。这样可以避免这个类的依赖未被满足导致的问题。
class B;
class A {
public:
void func(B& b);
};
class B {
public:
void func(A& a) {}
};
void A::func(B& b) {
b.func(*this);
}
四、总结
c++不允许使用不完整的类型是为了保证类型的安全性和编译器的可靠性。在使用时应该尽量避免使用不完整类型,可以完全定义类型、使用指针或引用的方式传递、或是先进行定义。合理的使用这些方法可以避免不完整类型的问题。
原创文章,作者:BJNKU,如若转载,请注明出处:https://www.506064.com/n/330173.html