1

有没有办法让用户输入引用随机类实例?我的意思是基于已经创建的那些?有点像一个开关,但没有写出开关内的每个实例?我希望我的代码更加通用,以便其他人可以添加它而无需更改开关或代码的其他部分。

我知道帖子的组织方式有点曲折,但我觉得这是在帖子上组织我的想法的最佳方式,所以请多多包涵。在最底部的代码中,我创建了一个指针来更改“test1”实例中的变量。我希望能够让程序能够获取用户输入来选择哪个类,然后在那里进行更改。我知道这种语法不起作用,但例如:

class test {
public:
    int number;
    int letter;
}
test classTest; //to get user input of which class he wants to select
                //to change a variable
cin >> classTest; //user inputs choice
test * classPointer; //pointer to variables
cin >> classPointer -> number;
cin >> classPointer -> letter;
//where classTest is actually not a normal instance, just a way to get user
//input to select which class instance variables he'd like to change

这是我的问题开始的一点背景,这个问题源于。如果您不关心它/需要它来回答我,您可以跳过它。我正在编写一个 RPG 游戏来练习我在 C++ 中所学的内容,并且我想让我编写的代码相当通用。例如,如果我有一个类可以创建某些在“城镇”中通用的对象。比如物品商店、旅馆等。在战斗系统中你可以选择使用物品。在该项目类别中,应该只列出可用的项目。没问题,我可以写大量的 if 和开关和布尔值——但是我不想为战斗系统中的每个项目都写所有这些,我想要某种机制来为我做到这一点。我相信如何调用指针的一些技巧将解决我的问题。但是,说了这么多,请不要被我的背景故事所牵扯。它只是为了帮助您了解我的思维过程,如果它不能解决这个问题,就这样吧,无论如何我都需要知道这些信息以获取指针。

#include <iostream>
#include <stdio.h>

class test {
public:
    int number;
    char letter;
    void function() {
        printf("Number = %d\nLetter = %c", number, letter);
    }
    test() {}
    test(int a, char b) : number(a), letter(b) {}
};

int main()
{
    test* pointer;
    test test1(1, 'c');
    pointer = &test1;
    test1.function(); //output initial result
    printf("\nEnter a new number: ");
    std::cin >> pointer -> number; //change number
    printf("Enter a new letter: ");
    std::cin >> pointer -> letter; //change letter
    test1.function(); //output changed result
    return 0;
}
4

1 回答 1

1

我对代码片段和密集的文本有点迷惑,但你描述的问题是一个相当普遍的问题。

要创建基于某个键的类型的对象,您可能希望将抽象工厂模式作为您的起点——在您附近的所有优秀教科书和更有信誉的 wiki 中都可以找到。如果它看起来对你的目的来说被夸大了,不要被推迟——就像所有的图案一样,你可以把它剪下来以满足你的需要。

本质上,对于您想要创建的每种类型的对象,您都需要一个知道如何制作它的工厂。制作此相关对象集合所需的所有工厂都应共享相同的接口。

要选择正确的工厂来创建请求的对象类,您需要一个键映射,即工厂的字符串。该地图取代了您可能想使用的 if-else/switches。如果您想尽量减少打字并混淆您的敌人和朋友,可以使用 Singleton 来针对密钥注册工厂,但请先阅读所有健康警告:

// 城镇中所有住宅的基类
类住宅
{
上市:
   虚拟〜住宅(){}
   虚拟住宅(整数,字符字母);
   虚拟 Enter() = 0;
   虚拟离开()= 0;
   // ... 无论您在城镇住宅中可以做什么其他常见的事情 */
};

// 一种住宅 - 随心所欲
类商店:公共住宅
{
   virtual Shop(int number, char letter)
     : 住宅(数字、字母)
   { /* 东西 */}
   虚拟回车();
   虚拟离开();
};

// 用于制作住宅类型的基础工厂类
类 AbstractDwellingFactory
{
上市:
   虚拟 DwellingFactory() {}
   虚拟住宅 * Create(int number, char letter) = 0;
};

// 所有住宅工厂的收集和注册 - 一个 Meyer's Singleton 方便起见
类 DwellingFactory
{
上市:
   静态 DwellingFactory & Instance()
   {
       static DwellingFactory theInstance;
       返回实例;
   }
   // 根据给定的类型和其他参数创建住宅 - 考虑智能指针而不是此处显示的原始指针
   住宅 * 创建(std::string const & 住宅住宅类型,整数,字符字母)
   {
      // 假设我们有一个匹配的工厂,让我们成为一个住宅。
      // 显然,在现实世界中这里需要一些错误检查
      return myAbstractDwellingFactoryMap[dwellingType].Create(number, letter);
   }
   无效寄存器(std::strinf 常量和住宅类型,AbstractDwellingFactory 常量和事实)
   {
      myAbstractDwellingFactory[dwellingType] = &fact;
   }
私人的:
   住宅工厂(){}
   // 类型映射的实际键
   std::map myAbstractDwellingFactoryMap;
};

// 一个通用的混凝土工厂
模板 <类型名 DwellingType>
类 ConcreteDwellingFactory : 公共 AbstractDwellingFactory
{
上市:
   ConcreteDwellingFactory(std::string const &dwellingType)
   {
      DwellingFactory::Instance().Register(dwellingType, *this);
   }
   // 工厂函数 - 注意我们可以在这里返回一个指向派生类型的指针 - 查找“co variant return types”
   DwellingType * Create(int number, char letter)
   {
      返回新的住宅类型;
   }

};

// 您要支持的每种住宅类型的工厂实例
static ConcreteDwellingFactory<Shop> shopFactory("Shop");

无效的一些函数()
{
   std::string 住宅类型;
   整数;
   字符字母;

   std::cin >> 住宅类型 >> 数字 >> 字母;
   住宅 *requestedDwelling(DwellingFactory::Instance().Create(dwellingType, number, letter));
   请求住宅->输入();// 等等
}


于 2013-10-16T01:34:59.480 回答