c++ - 是否可以引用随机类?

标签 c++ class pointers reference

有没有办法让用户输入来引用随机类实例?我的意思是基于已经创建的那些?有点像开关,但没有写出开关内的每个实例?我希望我的代码更具通用性,以便其他人可以在不更改开关或代码的其他部分的情况下向其添加内容。

我知道帖子的组织有点曲折,但我觉得这是在帖子上组织我的想法的最佳方式,所以请多多包涵。在最底部的代码中,我创建了一个指针来更改“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++ 中学习的内容,并且我想让我编写的代码相当通用。例如,如果我有一个类创建某些在“城镇”中通用的对象。比如 Prop 店,客栈等等。在战斗系统中你可以选择使用 Prop 。在该项目类别中,虽然应该只列出可用的项目。这没问题,我可以编写大量的 if、开关和 bool 值——但是我不想为战斗系统中的每个项目编写所有这些我想要某种可以为我完成的机制。我相信一些关于如何调用指针的技巧将解决我这里的问题。然而,尽管如此,请不要因为我的背景故事而分心。它只是为了帮助您了解我的思考过程,如果它不能解决这个问题,那就这样吧,无论如何我都需要知道这些信息以供引用。

#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;
}

最佳答案

我对代码片段和密集的文本有点迷惑,但你描述的那种问题是相当常见的。

要创建基于某个键的类型的对象,您可能希望将抽象工厂模式作为您的起点 - 在您附近的所有优秀教科书和更有信誉的 wiki 中都可以找到。如果它看起来对您的目的来说过于夸张,请不要推迟 - 与所有模式一样,您可以将其削减以满足您的需要。

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

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


// Base class for alldwellings in your town
class Dwelling
{
public:
   virtual ~Dwelling() {}
   virtual Dwelling(int number, char letter);
   virtual Enter() = 0;
   virtual Leave() = 0;
   // ... Whatever other common things you can do in a town dwelling */ 
};

// A type of dwelling - as many of these as you like
class Shop : public Dwelling
{
   virtual Shop(int number, char letter)
     : Dwelling (number, letter)
   { /* stuff */}
   virtual Enter();
   virtual Leave();
};

// Base factory class for making a type of dwelling
class AbstractDwellingFactory
{
public:
   virtual DwellingFactory() {}
   virtual Dwelling * Create(int number, char letter) = 0;
};

// Collection and registrar of all dwelling factories - a Meyer's Singleton for convenience
class DwellingFactory
{
public:
   static DwellingFactory & Instance()
   {
       static DwellingFactory theInstance;
       return theInstance;
   }
   // Create a dwelling from the given type and other parameters - consider smart pointers rather than the raw pointer shown here
   Dwelling * Create(std::string const & dwelling dwellingType, int number, char letter)
   {
      // Assuming we have a matching factory, make us a dwelling.
      // Obviously some error checking is required here in the real world 
      return myAbstractDwellingFactoryMap[dwellingType].Create(number, letter);
   }
   void Register(std::strinf const & dwellingType, AbstractDwellingFactory const & fact)
   {
      myAbstractDwellingFactory[dwellingType] = &fact;
   }
private:
   DwellingFactory() {}
   // The actual key to type mapping
   std::map myAbstractDwellingFactoryMap;
};

// A generic concrete factory
template <typename DwellingType>
class ConcreteDwellingFactory : public AbstractDwellingFactory
{
public:
   ConcreteDwellingFactory(std::string const & dwellingType)
   {
      DwellingFactory::Instance().Register(dwellingType, *this);
   }
   // Factory function - note we can return a pointer to a derived type here - look up 'co variant return types'
   DwellingType * Create(int number, char letter)
   {
      return new DwellingType;
   }

};

// A factory instance for each dwelling type you want to support
static ConcreteDwellingFactory<Shop> shopFactory("Shop");

void SomeFunction()
{
   std::string dwellingType;
   int number;
   char letter;

   std::cin >> dwellingType >> number >> letter;
   Dwelling *requestedDwelling(DwellingFactory::Instance().Create(dwellingType, number, letter));
   requestedDwelling->Enter(); // et cetera
}


关于c++ - 是否可以引用随机类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19393275/

相关文章:

pointers - 应该在64位x86中对指针比较进行签名还是不签名?

c++ - 在模板中存储静态变量

c++ - 在类 Bat 代码中,它给我错误 : call of overloaded ‘Bat()’ is ambiguous Bat();

c++ - 如何访问 C++ 链表中的对象数据?

java类关系,泛化实现关联聚合组合依赖

c++ - (2 个问题) 'class' 类型重定义(即使使用#pragma once),以及静态函数内部的静态成员对象初始化?

c - 带数组的后增量指针

c++ - 删除 C++ 中的多余空格

java - Class.forName android NoClassDefFoundError -> ClassNotFoundException

c++ - 在动态分配的多维数组之后清理