【Cpp 进阶】C++面向对象编程编译错误汇总

1. undefined reference to `vtable for Subject 肿么办?

C++提示编译时提示

undefined reference to vtable for 。。。

这是因为 类 在头文件中声明了 父类 的虚函数,但是没有实现虚函数。

总之,就是类里边的函数仅仅声明了,但是没有实现。(C++是不允许这样的(纯虚函数除外))

解决办法:

  • 在类的源文件中实现 虚函数 功能,或者定义为纯虚函数。

 

2. undefined reference to 'WinMain@16' 原因——找不到main()

undefined reference to ‘WinMain@16’ 意思为提示找不到 WinMain 函数,WinMain是windows程序的入口函数,有几种可能:

总之就是找不到main()函数的意思。

若本来想把本来就没有main()函数的文件编译成静态库或者.o,以供以后链接的时候再使用就需要指定 gcc 参数为 -c,意思是只编译不链接。

如果只加-o而不加-c选项,形如g++ test.cpp -o test (test.cpp中无main() ),那么就会出现这个错误。

这里有一个奇怪而且有趣的地方,举个例子——我的Observer.cpp 文件中调用了 Subject.cpp 的函数。

但是只编译的情况下,只要有相应的函数声明就行(不需要实现),编译器认为函数在别的文件实现了,认为可以放心去编译。(如果不理解,可以参考我的文章《【Cpp 基础】分离式编译模式》)

然后在链接的时候,将调用了的 Subject.cpp 的函数链接起来。

 

 

3. 解决C++代码中出现的“error: invalid use of incomplete type 'class'”问题

在C++编程过程中,我们有时会遇到“error: invalid use of incomplete type 'class'”这样的编译错误。这个错误通常出现在使用某个类的对象或引用时,编译器无法找到该类的完整定义。这种情况可能会导致代码无法正确编译和运行。本文将介绍该错误的原因,并提供一些解决方案。

首先,我们来看一个简单的示例代码,模拟出现这个错误的场景。

#include <iostream>

class ClassA; // 前向声明

class ClassB {
public:
    ClassB(ClassA& obj) : m_obj(obj) {}
    void print() {
        std::cout << "ClassB: " << m_obj.getData() << std::endl;
    }
private:
    ClassA& m_obj;
};

class ClassA {
public:
    ClassA(int data) : m_data(data) {}
    int getData() {
        return m_data;
    }
private:
    int m_data;
};

int main() {
    ClassA obj(10);
    ClassB b(obj); // 编译出错的位置

    return 0;
}

这个错误的原因是在ClassB的定义中,我们只是通过前向声明来引用了ClassA,但并没有提供ClassA的完整定义。因此,编译器不知道ClassA具体是什么样子,无法正确生成ClassB的代码。

解决这个问题的方法有几种。

第一种方法是把ClassA的定义放在ClassB之前。这样,当编译器遇到ClassB的定义时,它已经知道了ClassA的完整定义。

第二种方法是使用指针或引用来替代对象作为成员变量。这样做的好处是在声明ClassB时,我们只需要提供一个指针或引用类型,而不需要完整的类定义。

 

 

 

X-附录

1. 问题3解决:https://www.php.cn/faq/596636.html

 

X-扩展:C++对象基础——继承

在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承
派生类的定义格式
单继承的定义格式如下:
class<派生类名>:<继承方式><基类名> 
{ 
    <派生类新定义成员> 
};
其中,class是关键词,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。<继承方式>常使用如下三种关键字给予表示:
public 表示公有继承;
private 表示私有继承
protected 表示保护继承;
多继承的定义格式如下:
class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… 
{ 
    <派生类新定义成员> 
 };
可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个。
如果省略继承方式,对'class'将采用私有继承,对'struct'将采用公有继承。
也就是说
class Base1{}; 
struct Base2{}; 
class Derive:Base1,Base2{};

//相当于:
class Derive:private Base1, public Base2{};

 

 

 

posted @ 2024-01-10 21:55  FBshark  阅读(16)  评论(0编辑  收藏  举报