c++ - 访问数组中的对象重新创建对象?

标签 c++ windows user-interface

我正在制作主机游戏和 map 。 map 是一个 vector 数组。 vector 包含我打印到控制台的字符。我的代码:

“窗口.h”

#include <string>
#include <vector>

class Row {
public:
    std::vector<char> row;
    int id;
    Row();
    void printRow();
    void resetRow();
    void insertStringIntoRow(std::string toInsert, int startIndex);
    std::vector<char> getRow() {
        return row;
    }
};

class Window {
public:
    void showMap();
    void writeToMap(std::string stringToInsert, int rowNum, int startIndex);
    void writeInRectangle(std::string stringToWrite, int rowNum, int startIndex);
    void setCursorToPosition(int x, int y);
    void resetMap();
    Row getRowAt(int index);
};

void initColors();
void setWindow(Window windowToSet);
Window getGameWindow();

“窗口.cpp”

#include "Window.h"
#include <iostream>
#include <Windows.h>
#include <WinBase.h>
#include <stdlib.h>
#include "color.h"

using namespace eku;

Row map[25];

//Class Window
void Window::showMap() {
    setCursorToPosition(0, 0);
    for (int i = 0; i < 25; i++) {
        getRowAt(i).printRow();
    }
}

void Window::writeToMap(std::string stringToInsert, int rowNum, int startIndex) {
    Row r = getRowAt(rowNum);
    r.insertStringIntoRow(stringToInsert, startIndex);
}

void Window::writeInRectangle(std::string stringToWrite, int rowNum, int startIndex) {
    if (startIndex != 0) {
        std::string topbar = "~";
        for (int i = 0; i < stringToWrite.length() + 2; i++) {
            topbar += ' ';
        }
        topbar += '^';
        getRowAt(rowNum - 1).insertStringIntoRow(topbar, startIndex - 1);
    }

    std::string toInsert = "~ ^" + stringToWrite + "~ ^";
    getRowAt(rowNum).insertStringIntoRow(toInsert, startIndex - 1);

    if (startIndex != 25) {
        std::string bottombar = "~";
        for (int i = 0; i < stringToWrite.length() + 2; i++) {
            bottombar += ' ';
        }
        bottombar += '^';
        getRowAt(rowNum + 1).insertStringIntoRow(bottombar, startIndex - 1);
    }
}

void Window::setCursorToPosition(int x, int y) {
    HANDLE hOut;
    COORD Position;
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    Position.X = x;
    Position.Y = y;

    SetConsoleCursorPosition(hOut, Position);
}

void Window::resetMap() {
    for (Row row : map) {
        row.resetRow();
    }
}

Row Window::getRowAt(int index)
{
    return map[index];
}

//Class Row
const char WHITEBACKCOL = '~';
const char DEFCOL = '^';

int i = 0;

Row::Row() {
    row.resize(80, ' ');
    id = i;
    i++;
}

void Row::printRow() {
    for (int i = 0; i < row.size(); i++) {
        switch (row[i]) {
        case WHITEBACKCOL:
            setcolor(black, white);
        case DEFCOL:
            setcolor(white, black);
        default:
            std::cout << row[i];
        }
    }
}

void Row::resetRow() {
    row.resize(80);
    for (int i = 0; i < 80; i++) {
        row[i] = ' ';
    }
}

void Row::insertStringIntoRow(std::string toInsert, int startIndex) {
    int endIndex = (startIndex + toInsert.length());
    int stringPos = 0;
    for (int i = startIndex; i < endIndex; i++) {
        if (i < row.size() - 1) {
            row.at(i) = toInsert[stringPos];
        }
        else {
            row.push_back(toInsert[stringPos]);
        }
        stringPos++;
    }
}
Window defWindow;

void initColors() {
    concolinit();
    setcolor(white, black);
}

void setWindow(Window windowToSet) {
    defWindow = windowToSet;
}

Window getGameWindow() {
    return defWindow;
}

" main.cpp "

#include <iostream>
#include "GameEngine.h"
#include "Window.h"

int main() {
    setWindow(Window());
    initColors();

    getGameWindow().writeInRectangle("Hia", 1, 10);

    getGameWindow().showMap();
}

每当我调用 showMap() 时,我得到的只是一个空白的控制台。它似乎只打印默认的空间映射而不是我输入的文本。我还尝试仅使用 printRow() 来打印我编辑的单行,但它们也只显示空格。 我能够在 insertStringIntoRow() 方法中查看 vector 行的更改,但是即使更改应该在那里,它们也没有显示在其他任何地方。几乎每次我访问它时,我的 Row 对象都会被创建。我是 C++ 的新手,所以感谢您的帮助。提前致谢!

最佳答案

此功能使用不当。警告标志是它是非常量的,但用作访问器。它返回 vector 的拷贝,而不是引用。

std::vector<char> getRow() {
    return row;
}

您调用它的方式,您希望它就地修改该行,但您实际上所做的只是修改该行的拷贝,然后立即将其丢弃。示例:

getRowAt(rowNum).insertStringIntoRow(toInsert, startIndex - 1);

解决此问题的简单方法是从 getRow() 返回一个引用:

std::vector<char> & getRow() {
    return row;
}

另一件需要修复的事情是将它分配给一个临时变量,而不是直接使用它。在这种情况下,您可以将临时文件设为引用:

Row & r = getRowAt(rowNum);
r.insertStringIntoRow(stringToInsert, startIndex);

实现它的正确方法是提供一个常量版本,这样它仍然可以在调用者不想修改的常量对象上调用

const std::vector<char> & getRow() const {
    return row;
}

我只把这个额外的部分放在这里是因为这是一个很好的做法,但你不应该在这个程序中这样做。它会使你的代码变得困惑,因为它已经充满了更糟糕的做法 =)

关于c++ - 访问数组中的对象重新创建对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31130590/

相关文章:

c++ - 将用户输入复制到字符 vector

windows - 帮助 Windows Visa/7 UAC 文件系统虚拟化

user-interface - meteor 与框架实现

python - Qt 平台插件 'windows' - py2exe

c++ - 变量在析构函数调用中不递增?

java - 没有使用 JNA 获取 C++ 结构

c++ - 将 Windows 套接字程序移植到 Unix : Alternative for winsock32 APIs in unix

windows - 在 Windows 上使用音频检测进程

python - 如何在 Windows 上有效地 "replace" `os.execvpe` - 如果 "child"进程是交互式命令行应用程序?

java - 关闭窗口而不关闭应用程序