android - 使用多个基类时出现链接错误

标签 android c++ inheritance linker android-ndk

我有两个基类; “MemoryManagedObject”和“Gameobject”。我的想法是让我自己的类继承自“Gameobject”,而“Gameobject”继承自“MemoryManagedObject”。

#ifndef _GAME_OBJECT_H
#define _GAME_OBJECT_H

#include "MemoryManagedObject.h"

class GameObject : public MemoryManagedObject
{
public:
    GameObject() { }
    GameObject(bool UseMemPool): MemoryManagedObject(UseMemPool) { }
    virtual ~GameObject() { }

    long GetGameObjectID();

protected:
    long mGameObjectID;
};

inline long GameObject::GetGameObjectID()
{
    return mGameObjectID;
}

#endif


#ifndef _MEMORY_MANAGED_OBJECT_H
#define _MEMORY_MANAGED_OBJECT_H

#include <new>

class MemoryManagedObject
{
public:
    MemoryManagedObject();
    MemoryManagedObject(bool UseMemPool);
    virtual ~MemoryManagedObject() { DecreaseRefCount(); }

    bool IsAllocatedWithMemPool();
    void* operator new(size_t size);
    void* operator new(size_t size, bool UseMemPool);
    void operator delete(void* obj);
    long GetRefCount();

private:
    void IncreaseRefCount();
    void DecreaseRefCount();

    long mRefCount;
    bool mAllocatedWithMemPool;
};

#endif

但是我的编译器(android-ndk,gcc 4.4.1 afaik)在函数中抛出“ undefined reference ”链接器错误:~MemoryManagedObject 和 ~GameObject:对 MemoryManagedObject::delete(void* obj) 和 MemoryManagedObject::的 undefined reference 减少引用计数

这是为什么?我已经把所有的方法都写在.cpp 文件中,这些文件包含在编译中;我认为我声明虚拟析构函数的方式有问题,但我不知道为什么。

编辑:发布测试类和 cpp 文件:

测试类1.h

#ifndef _TEST_CLASS_1_H
#define _TEST_CLASS_1_H

#include "GameObject.h"

class TestClass1 : public GameObject
{
public:
    TestClass1();
    TestClass1(bool UseMemPool);
    ~TestClass1();

    void TestMe();
};

测试类1.cpp

#include "TestClass1.h"

TestClass1::TestClass1()
{

}

TestClass1::TestClass1(bool UseMemPool): GameObject(UseMemPool)
{

}

TestClass1::~TestClass1()
{

}

void TestClass1::TestMe()
{

}


#endif

游戏对象.cpp

#include "GameObject.h"

GameObject::GameObject()
{

}

GameObject::GameObject(bool UseMemPool): MemoryManagedObject(UseMemPool)
{

}

GameObject::~GameObject()
{

内存管理对象.cpp

#include "MemoryManagedObject.h"
#include "Engine.h"

#include <stdint.h>


MemoryManagedObject::MemoryManagedObject()
{
    mAllocatedWithMemPool = false;
    IncreaseRefCount();
}

MemoryManagedObject::MemoryManagedObject(bool UseMemPool)
{
    mAllocatedWithMemPool = UseMemPool;
    IncreaseRefCount();
}

MemoryManagedObject::~MemoryManagedObject()
{
    DecreaseRefCount();
}

long MemoryManagedObject::GetRefCount()
{
    return mRefCount;
}

void MemoryManagedObject::IncreaseRefCount()
{
    mRefCount++;
}

void MemoryManagedObject::DecreaseRefCount()
{
    mRefCount--;
    if (mRefCount <= 0)
    {
        delete this;
    }
}

bool MemoryManagedObject::IsAllocatedWithMemPool()
{
    return mAllocatedWithMemPool;
}

void* MemoryManagedObject::operator new(size_t size)
{
    Engine* engine = Engine::GetEngine();
    void* alloc;

    alloc = engine->GetMemoryManager()->Allocate(size);

    return alloc;
}

void* MemoryManagedObject::operator new(size_t size, bool UseMemPool)
{
    Engine* engine = Engine::GetEngine();
    void* alloc;

    alloc = engine->GetMemoryManager()->Allocate(size, UseMemPool);

    return alloc;
}


void MemoryManagedObject::operator delete(void* obj)
{
    Engine* engine = Engine::GetEngine();
    MemoryManagedObject* memObj = (MemoryManagedObject*)obj;

    engine->GetMemoryManager()->Deallocate(obj,memObj->IsAllocatedWithMemPool());
}

}

最佳答案

您正在内联编写虚拟析构函数,这通常会导致它们作为弱符号在每个编译单元中发出。此外,由于类中的第一个(也是唯一一个)虚函数是析构函数,因此它将成为关键函数,vtable 将通过它发出。

我猜想这两个东西相互作用不好,导致内联析构函数不包含在最终链接中。

无论如何,解决方案是将虚拟析构函数的定义移到 cpp 文件中。除非您在堆栈上声明对象的实例,否则除非通过 vtable,否则永远不会调用析构函数。

关于android - 使用多个基类时出现链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8958181/

相关文章:

inheritance - 多重继承什么时候派上用场?

android - View.getWidth() 在 onCreate 方法中不起作用?

android - 如何在 fragment 中添加函数

c++ - WinPE 2.0 (Vista) - 使用 VBSCRIPT 和 HTA 应用程序寻找 BrowseForFolder 的解决方案

c++ - 将目录添加到不带CMakeLists.txt的CMake项目中

c++ - 为什么编译器会尝试将指针传递给引用而不是此代码片段中的指针?

android - 在 Android 中访问 Web 上 protected 图像

android - 如何在Flutter中打印列表后防止自动向下滚动

c++ - 有没有人在 Windows 7 机器上成功编译过 Vowpal Wabbit?

java - 扩展类中的 ClassName.this