- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力让用户选择数据类型模板将被创建为。由于模板类型必须在编译时定义,我必须指定数据类型模板将使用 eg(string,int, so on),但这意味着我不能在后面更改它,从让我们说字符串到 int 即使我的模板支持它,因为模板类对象被声明为字符串。我的类(class)声明如下:
template <class T>
class MyHashTable
{
public:
string deleted="deleted";
unsigned short tableSize;
// array of vectors, hash table container
vector<T>* myTable;
vector<T>* deletionTable;
MyHashTable(unsigned short tableSize) : myTable(new vector<T>[tableSize]), deletionTable(new vector<T>[tableSize])
{
this->tableSize=tableSize;
}
类外的对象声明
MyHashTable <string>* myChainedTable=NULL ;
string tableType;
对象初始化
if (myChainedTable)
{
delete myChainedTable;
myChainedTable=NULL;
}
getType();
if (!myChainedTable)
{
if (tableType=="string")
myChainedTable= new MyHashTable<string>(length);
if (tableType=="char")
MyHashTable<char> myChainedTable(length); // no difference with or without using new keyword
if (tableType=="double")
MyHashTable<double> myChainedTable(length);
if (tableType=="float")
MyHashTable<float> myChainedTable(length);
if (tableType=="int")
MyHashTable<int> myChainedTable(length);
cout<<tableType<<" table of size "<< length<<" created"<<endl;
我尝试将类对象传递给函数而不是将其作为全局变量,但也无法使其工作。
我真正需要的是单个模板对象,它可以有:int、string、char、double、float 类型,我有 3 个函数需要访问模板类对象,并且有 5 个不同的对象和 200 行 if针对每种情况的陈述听起来像是最糟糕的解决方案。我在这上面停留了一段时间,只是不知道该怎么做,我们将不胜感激。
void getType()
{
cout<<"Enter table type, types available: int, char, float, double, string.\n";
tableType=getInput();
while((tableType != "int")&&(tableType !="float")&&(tableType !="double")&&(tableType!="char")&&(tableType !="string"))
{
cout<<"Invalid type, please try again "<<endl;;
tableType=getInput();
}
}
最佳答案
您的问题在模板和变体之间。
模板是编译时的。所以你必须在编译时为你的对象选择你想要的类型。您的条件方法不起作用(请参阅问题评论)。
另一方面,您似乎需要在运行时动态选择类型。
如果您想继续使用模板方式:(根据评论进行编辑)
您需要让所有模板都继承自一个多态基类(一个具有虚函数的通用接口(interface))。示例:
class MyHashBase // common base class for all templates
{
public:
virtual void addElement(void *ptrelem) = 0; // adding an element must be implemented by template. With void* since future template type unknown from base class
virtual void displayAll() = 0;
};
然后模板需要实现虚函数:
template <class T>
class MyHashTable : public MyHashBase
{
public:
unsigned short tableSize;
vector<T>* myTable; // I leave it as it is, but you could implement these as vector<T> instead of vector<T>*
vector<T>* deletionTable;
MyHashTable(unsigned short tableSize) : myTable(new vector<T>[tableSize]), deletionTable(new vector<T>[tableSize]), tableSize(tableSize)
{ }
void addElement(void* ptrelem)
{ myTable->push_back(*reinterpret_cast<T*>(ptrelem)); } // reinterpret the void* of the common interface as a T*
void displayAll()
{ copy(myTable->begin(), myTable->end(), ostream_iterator<T>(cout, "\n")); }
};
然后你可以得到你的 myChainedTable
是一个指向公共(public)基类型的指针,并按照您对字符串大小写所做的方式初始化此指针(即使用 new
)。
MyHashBase *myChainedTable = nullptr;
//...
if (tableType == "string")
myChainedTable = new MyHashTable<string>(length);
else if (tableType == "double")
myChainedTable = new MyHashTable<double>(length);
//...
然后您可以使用通用 API,例如 tableType
是"double"
:
double d1 = 3.1415, d2 = 1.4142;
myChainedTable->addElement(&d1); // ATTENTION: you must ensure to provide pointer to the correct data type
myChainedTable->addElement(&d2);
myChainedTable->displayAll();
如果在调用代码中需要,你肯定会有一个 coupe of,但你可以通过仔细设计基类将它们减少到最少(例如,你可以添加一个虚拟克隆函数,无需调用者知道类型)。
但是,对基类的公共(public)功能使用单一签名是很麻烦的。为了使虚拟化成为可能,您需要通过 void*
传递参数指针不是很好而且很容易出错。
变体的替代方式
你也可以使用 boost variants 用于管理具有动态类型定义的对象。
在这种情况下,您不需要自己的数据结构模板。你会创建一个 MyHashTable
具有 boost::variant< int, std::string, ... >
类型的元素.
如果您知道对象的类型(如在您的 myChainedTable
中),您可以使用以下命令访问对象的正确值:boost::get<int> (element)
(或 boost::get<string>()
,...)。
如果您不知道元素的类型,您可以使用“访问者”的概念来根据类型自动选择要执行的适当函数。
编辑: union 的替代方式:
如果您不允许使用变体,另一种选择是使用 union
.我不知道你分配的主题,但你可以选择是使用 union 来定义元素(如变体,没有模板)还是像你一样使用模板类型,但定义 myChainedTable
成为指向不同模板实例化的指针的 union 。但是,是的,它需要很多 if
小...
关于c++ - 如何创建用户定义类型模板类对象 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26562371/
在complier.h中有一个宏定义如下: # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) 但是这里我有一个问题,就是哪里
curl_easy_setopt 的选项在哪里?定义?我试图寻找 CURLOPT_VERBOSE 和其他一些整数值,但这些似乎没有在 curl.h 中明确定义。 最佳答案 第 792 行: #ifde
我确实有一个如下所示的类(class): //.h file class __declspec(dllimport) MyClass { public: //stuff pri
作者: zhuwenzhuang, 2024.05.08. 阅读前假设读者熟悉数据库使用,了解 SQL 的语法和关系算子的大概含义, 能通过 EXPLAIN 命令查看数据库执行计划. 0 前言
我似乎无法找到是否可以声明一个 header 对象以便在响应 header 中重用它,有一些示例定义了响应模式的对象,但它不会转置为响应 header 。我只设法制作了一个可重用的响应对象,如下所示:
css 选择器 * + * 实际上是什么意思?当您执行检查元素时,您可以在谷歌浏览器的控制台中看到它。在我看来,这似乎是对 "Every second child"应用一种风格,但仍然想确定。谁能帮我
我试图弄清楚基本的IO Haskell 函数是定义好的,所以我使用了this reference我到了putChar函数定义: putChar :: Char -> IO () putChar
我得到了一个自动生成的文件,该文件定义了程序集属性,我正在尝试理解内容。 [assembly: global::System.Runtime.Versioning.TargetFrameworkAtt
This文档演示了如何检查变量是否先前已在 gnuplot 脚本中定义。 文档中的示例: a = 10 if (exists("a")) print "a is defined" if (!exist
好吧,这是一个相当基本的问题:我正在关注 SICP 视频,我对 define、let 和 之间的区别有点困惑设置!. 1) 根据 Sussman 在视频中的说法,define 只允许为变量附加一个值一
我一直在尝试定义一个包含只能具有以下三个值之一的字段的 XSD: 绿色 红色 蓝色 本质上,我想在架构级别定义严格的枚举。 我的第一次尝试似乎是错误的,我不确定修复它的“正确”方法。
有人可以定义“POCO”到底是什么意思吗?我越来越频繁地遇到这个术语,我想知道它是否仅与普通类有关还是意味着更多? 最佳答案 “普通旧式 C# 对象” 只是一个普通的类,没有描述基础结构问题或域对象不
在我经常看到的一些django模型中 myfield = models.CharField(_('myfield')) class_name = models.CharField(_('Type'),
每当 BOOL 数据类型不容易预定义时,我都会使用以下定义进行 boolean 运算, typedef unsigned char BOOL; (由于内存使用)。 我意识到出于性能原因,使用本地总线宽
l_ABC_BEANVector = utilRemote.fnGetVector("ABC_COVBEANVector"); 编码的含义是什么?任何帮助,我真的很感激。谢谢 最佳答案 唯一可以肯定地
我正在使用 javacc 开发一个项目,我遇到问题并需要一些帮助,我的文件中有这样的内容: STRING COPYRIGHT (C) 2003, 2004 SYNOPSYS, INC.; 我为单词 S
我想弄清楚基本的 IO定义了 Haskell 函数,所以我使用了 this reference然后我到了 putChar函数定义: putChar :: Char -> IO () putCha
我在具体类中使用 @property 定义 getter 时遇到问题。这是Python代码: from abc import ABCMeta, abstractproperty class abstr
我正在为大学用 C 语言编写一个小游戏,但我陷入了困境。我(在头文件中)有这个结构: typedef struct{ game_element field[MAX_ROWS][MAX_COLU
我一直在 .l 文件中创建标记定义。由于数据集数量庞大,它变得有点乏味。有没有办法读取文件中的所有单词,例如包含所有名词的 noun.txt 并给所有名词一个标记。 基本上,我想自动化这部分: %%
我是一名优秀的程序员,十分优秀!