我有一个类,它将一些结构联合起来,例如:
struct _tRack1{
unsigned char shelf1;
unsigned int shelf2;
float shelf3;
};
struct _tRack2{
char shelf1;
int shelf2;
char shelf3;
char shelf4;
};
struct _tRack3{
char shelf1;
unsigned int drawer[5];
};
class Catalog
{
public:
_tRack1 *localdata1;
_tRack2 *localdata2;
_tRack3 *localdata3;
int index;
Catalog(int recktype){
localdata1 = NULL;
localdata2 = NULL;
localdata3 = NULL;
index = recktype;
switch(recktype){
case 1: *localdata1 = new _tRack1; break;
case 2: *localdata2 = new _tRack2; break;
case 3: *localdata3 = new _tRack3; break;
}
};
~Catalog(){
if(localdata1 != NULL) delete localdata1;
if(localdata2 != NULL) delete localdata2;
if(localdata3 != NULL) delete localdata3;
};
int someMethod(_tRack1){/*...*/};
int someMethod(_tRack2){/*...*/};
int someMethod(_tRack3){/*...*/};
};
int main()
{
Catalog *foo = new Catalog(1);
Catalog *bar = new Catalog(3);
/*...*/
if(foo->index>1) foo->localdata1->shelf1=-3;
else foo->localdata1->shelf1=3;
if(bar->index>1) bar->localdata1->shelf1=-3;
else bar->localdata1->shelf1=3;
if(bar->index==3) bar->localdata3->drawer[0] = 0xDEADBEAF;
/*...*/
delete foo;
delete bar;
return 0;
}
我知道将结构公之于众并不好,但在现实生活中结构非常复杂,因此无法创建访问单独结构域的方法。 我想找到一种隐藏结构类型的方法。要访问这样的数据:
if(foo->index>1) foo->data->shelf1=-3;
else foo->data->shelf1=3;
if(bar->index>1) bar->data->shelf1=-3;
else bar->data->shelf1=3;
if(bar->index==3) bar->data->drawer[0] = 0xDEADBEAF;
有可能吗?
答案 0 :(得分:3)
你应该扔掉迄今为止所做的任何事情。然后阅读一本关于面向对象编程的书,而不是从头开始。
简单来说,您应该创建一个基类Rack,然后从中继承特定的Rack类型(即派生类)。目录或任何其他类不应该知道从Rack派生的对象的细节。它应该要求Rack派生的对象通过调用他们的虚拟方法来执行操作,而不是要求/访问他们的私有细节。
而且 - 忘记现在存在新的和删除。你还不需要它。这会让你的代码变得更糟。
答案 1 :(得分:0)
应该在Catalog中创建一个get方法,它可以在指定参数之后返回结构中的所有成员。 所以:
void Catalog::getValue(char* member, char &value)
{
switch(index)
{
case 2:
if(member="shelf1") value = localdata2->shelf1;
if(member="shelf3") value = localdata2->shelf3;
break;
case 3:
if(member="shelf1") value = localdata3->shelf1;
break;
case 3: break;
}
}
和另一个浮动值等等。
答案 2 :(得分:0)
当您仅通过指针访问目录(项目)时,它是抽象类的一个很好的候选者。然后机架将从此基类继承:
class CatalogItem { // I've just rename it not to confus with yours
private:
int index; // you need this
public:
CatalogItem(int recktype) : index(recktype) { }
int getType() { return index; }
virtual ~CatalogItem() {} // Virtal destructor so that the real class destructor is called
virtual int someMethod() = 0; // Pure virtual function. You can never create object directly
};
您可以按如下方式创建结构或类_tRack1:
class _tRack1 : public CatalogItem {
public:
unsigned char shelf1; // Original structure, but better'd hide it later
unsigned int shelf2;
float shelf3;
_tRack1() : CatalogItem (1) {};
int someMethod() { /* implementation for type 1 */ return 0; };
};
对_tRack2和_tRack3执行类似操作。你的主要看起来像:
CatalogItem *foo = new _tRack1; // pointer to a real consistent object
CatalogItem *bar = new _tRack3;
...
if (foo->getType()==1) static_cast<_tRack1*>(foo)->shelf1 = 3; // object specific setting
foo->someMethod(); // call of method. You don't have to care about index anymore.