如何创建对类(C++)[已关闭]

6ss1mwsb  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(165)

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
9小时前关门了。
Improve this question
我试图创建一个包含不同类对的Map。但是由于某种原因我无法完成它。
有人知道我的代码有什么问题吗?
这是发生错误的位置

#pragma once
#include <iostream>
#include "Piece.h"
#include <map>
#include "Knight.h"

std::map<char, Piece> pieces_types;

class Piece;

class Board
{
public:
    Board();
    ~Board();

private:
    void init_map()
    {
        pieces_types.insert(std::pair<char, Piece>('K', Knight));
    }
};

Piece是一个纯抽象类,Knight是Piece的继承者。

#pragma once
#include <iostream>
#include "Piece.h"

class Knight : public Piece
{

};

这就是我在
"Knight":非法将此类型用作表达式

deyfvvtc

deyfvvtc1#

'Knight': illegal use of this type as an expression你可以在其他语言中使用类型名作为一个实际值,但c++除外。
要创建一个从片段字符到片段上某个操作(如获取其名称或示例化示例)的查找表,最简单的方法是使用switch语句(因为只有6个片段,所以不会太麻烦):

#include <memory>

std::unique_ptr<Piece> make_piece(char c) {
    switch (c) {
        case 'K': return std::make_unique<Knight>();
        // etc...
    }
}

另一个选择是std::mapchar到工厂类的示例或一些模板编程,但对于c++的新手来说,这似乎有点过头了,特别是当只有6个类型,并且知道永远不会有更多或更少的类型时。

ncecgwcz

ncecgwcz2#

在c++中存储多态性数据与其他语言有很大的不同
java :

public class Board {

    private static Map<Character, Piece> pieceTypes = new HashMap<>();

    private void initMap() {
        pieceTypes.put('K', new Knight());
    }
}

您可以直接将Knight存储在Piece中,因为在java中它存储为引用
做同样事情的C++代码:

std::map<char, std::unique_ptr<Piece>> pieces_types;

class Board
{
private:
    void init_map()
    {
        pieces_types.insert(std::pair<char, std::unique_ptr<Piece>>('K', new Knight()));
    }
};

您可以看到,我在Map中存储的是std::unique_ptr<Piece> s,而不是Piece s
这里的std::unique_ptr<>是一个指针,类似于java中的引用,通过存储指针可以将不同类型的数据放在一个容器中
尽管这不是唯一的办法。
那么为什么c++不允许将派生类的数据存储在基类的容器中呢?你可以这样想:
在堆栈上分配并初始化具有 * 自动存储持续时间 * 的对象,如

Piece p1;

它的大小必须是已知的,并且是固定的。在c++中,函数的运行时堆栈大小是在编译时计算的。当你调用一个函数时,它总是首先分配堆栈内存。
因此,将派生对象赋给它是病态的:

Knight p2;
p1 = p2; // ill-formed

因为Knight的大小可能大于Piece,所以p1可能没有可用空间来存储Knight
但如果p1是一个指针,并且对象具有 * 动态存储持续时间 *,则有可能:

std::unique_ptr<Piece> p1{ new Piece() }; // { new Piece } is also OK
p1 = new Knight(); // OK

这里的两个对象是在堆上动态分配的,它们不占用堆栈内存
回到您的示例,将Knight存储到pair<char, Piece>的第二个槽是病态的,因为pair只是两个值的 Package 器,带有 * automatic storage duration *

相关问题