我尝试创建一个拼贴系统,用于创建拼贴的单个实例,并将拼贴添加到拼贴数组,允许您调用Tile::s_tileList[1]
来获取污垢拼贴。
但是,我遇到了一些问题。这是完整的磁贴代码:
tile.h
#pragma once
class Tile {
public:
static const Tile s_tileList[128]
static const Tile s_dirt;
Tile(int tileId);
virtual ~Tile();
protected:
private:
int m_tileId;
};
tile.cpp
#include "tile.h"
#include "tile_dirt.h"
const Tile Tile::s_dirt = TileDirt(1); // This line errors
Tile::Tile(int tileId) {
s_tileList[tileId] = *this;
m_tileId = tileId;
}
Tile::~Tile() {
}
tile_dirt.h
#pragma once
#include "tile.h"
class TileDirt : Tile {
public:
TileDirt(int tileId);
virtual ~TileDirt();
protected:
private:
};
当我尝试将s_dirt
分配给TileDirt
时,我收到以下错误:
conversion to inaccessible base class "Tile" is not allowed
我在这里做错了什么?
我尝试过:
static const Tile* s_dirt;
并指定它:
const Tile* Tile::s_dirt = new TileDirt(1);
但这只会增加另一个错误:no suitable constructor exists to convert from "const Tile *" to "Tile"
答案 0 :(得分:3)
在C ++中,类型Foo
的变量表示一个足以容纳Foo
对象的内存块(基本上完全正确)。它正是Foo
类型的数据。
如果您尝试在该内存中放入其他内容,您将获得从object slicing到未定义行为(这是不好的)的任何内容。
在许多其他语言(Java,C#,两个名称)中,类型Foo
的变量实际上代表了其他地方Foo
数据的句柄,或者可能是Foo
的派生类。通常这些是垃圾收集的,这是一个非确定性系统,在运行时引擎确定它们名义上无法从用户代码中访问之后,您的对象将在未来的某个未知点被销毁。
要在C ++中模拟这个,你需要一个智能指针 - std::unique_ptr<Foo>
或std::shared_ptr<Foo>
。这些在垃圾收集智能指针上并不完整,但除非您正在制作自引用数据,否则它们通常都足够好。在C ++中你必须考虑的一件事是“谁拥有这些数据的生命周期”。
std::shared_ptr
通常最容易使用。
将Tile
个实例替换为std::shared_ptr<Tile>
,将new Tile(blah)
的号码替换为std::make_shared<Tile>(blah)
。
接下来,默认情况下,C ++中的class
继承是私有的 - 除了您自己类型的实例之外,没有人知道您是父类的子级。如果您想要公共继承,请使用public Tile
。
您希望让Tile
构造函数将自身的副本存储在静态数组中是不好的。不要在构造函数中做那种事情,让它在构造函数之外完成。 (生成一个指向这个的共享指针有点烦人:最简单的方法实际上效果不好)
答案 1 :(得分:0)
错误与您问题的标题不符。
const Tile Tile::s_dirt = TileDirt(1); // This line errors
您正在声明一个全局常量(不是宏常量,而是内存分配常量,类似于全局变量)。
如何在“主要”功能上进行测试,放弃全局内容,以及常量,首先:
int main(...)
{
Tile* MyTyle = new TileDirt();
}
然后,如果确实需要,请更改为全局成员,以及常量成员?