我一直在用C ++实验室解决这个问题。据我所知,除了我的教授在我们的任务中规定的这一条款外,我所有工作都有效:
源文件中的类声明顺序是InventorySystem,InventoryItem,Product,eProduct。由于InventorySystem包含InventoryItem指针数组,因此您必须在InventoryItem上使用前向声明
所以InventoryItem - >产品 - > eProduct在派生的heriarchy中彼此相关,我们的任务是编写heirarchy与InventorySystem类相结合来管理指向eProduct对象的指针数组。
不幸的是,我所有的StackOverflow帖子让我得出的结论是,对我的要求是不可能的。据我理解前向声明,"通知编译器该类存在"真的很有用。任何与代码结构或定义相关的上下文都不能用于前向声明 - 这似乎与我实验室的其他要求直接冲突,因为InventorySystem有一个名为BuildInventory的方法,它解析格式化的文本文件并动态分配指向eProduct对象的指针数组。这不需要"前向声明的构造函数"宾语?
我真的,真的希望我只是成为C ++的新手并且我被大量误导,因为这个问题一直让我疯狂。
提前感谢您的帮助。
PS:对于功能名称和变量的奇怪外壳感到抱歉,这就是我的教授在我们的任务中编写套管的方式,而且我认为仅仅按照他所建立的内容滚动更安全。
//Format for text file is Name;Quantity;Price;Condition
void BuildInventory()
{
ifstream fin ("in.txt");
string name="";
string Buffer = "";
int quantity = 0;
double price = 0.0;
int temp = 0;
if (!fin) {
cout << "ERROR: Failed to open input file\n";
exit(-1);
}
while ( getline (fin, Buffer, ';') ) {
string condChar = "";
Condition condition = NEW;
name = Buffer;
getline (fin, Buffer, ';');
quantity = atol (Buffer.c_str ( ) );
getline (fin, Buffer, ';');
price = atof (Buffer.c_str( ) );
getline (fin, Buffer, '\n') ;
condChar = Buffer.c_str();
if(condChar.compare("R") == 0)
condition = REFURBISHED;
else if(condChar.compare("U") == 0)
condition = USED;
else if(condChar.compare("D") == 0)
condition = DEFECTIVE;
ep = new eProduct(name, quantity, price , condition);
ItemList[ItemCount] =ep;
++ItemCount;
fin.ignore(1, '\n');
}
fin.close();
Sort();
}
以下是InventorySystem动态分配的指针数组必须指向的对象层次结构的构造函数(都指向eProducts)
//Constructor of eProduct
eProduct(string Name, int Quantity, double Price, Condition condition)
:Product(Name, Quantity, Price)
{
this -> condition = condition;
}
//Constructor of Product
Product():ProductID(0), Price(0.0){}
Product(string Name, int Quantity, double Price)
:InventoryItem(Name, Quantity)
{
this -> Price = Price;
this -> ProductID = generateProductID();
}
//Constructor of InventoryItem
InventoryItem(std::string Name, int Quantity)
{
this -> Name = Name;
this -> Quantity = Quantity;
}
答案 0 :(得分:3)
秘诀在于教授给你的指示,以及你自己的描述:
源文件中的类声明顺序是InventorySystem,InventoryItem,Product,eProduct。由于 InventorySystem包含InventoryItem指针数组,您必须在InventoryItem上使用前向声明
我们的任务是将heirarchy与InventorySystem类结合起来,将管理指针数组写入eProduct对象。
所以你需要这样的东西:
class InventoryItem; // forward declaration
class InventorySystem
{
...
InventoryItem* ItemList[TheArraySizeHere]; // array of InventoryItem pointers
...
};
class InventoryItem
{
...
};
class Product : public InventoryItem
{
...
};
class eProduct : public Product
{
...
};
由于eProduct
派生自InventoryItem
,您可以将eProduct
指针存储在InventoryItem
指针数组中。
这是拼图的另一部分。您无法在BuildInventory()
类声明中实现InventorySystem
inline ,因为尚未声明eProduct
类。 BuildInventory()
的实施需要在eProduct
定义后分离和实施,例如:
class InventoryItem; // forward declaration
class InventorySystem
{
...
InventoryItem* ItemList[TheArraySizeHere]; // array of InventoryItem pointers
...
void BuildInventory();
};
class InventoryItem
{
...
};
class Product : public InventoryItem
{
...
};
class eProduct : public Product
{
...
};
...
void InventorySystem::BuildInventory()
{
// implementation here ...
}
通常将所有声明放在.h
文件中,将所有实施放在.c
/ { {1}}文件.cpp
是#include
文件,例如:
Inventory.h:
.h
Inventory.cpp:
#ifndef InventoryH
#define InventoryH
class InventoryItem; // forward declaration
class InventorySystem
{
...
InventoryItem* ItemList[TheArraySizeHere]; // array of InventoryItem pointers
...
};
class InventoryItem
{
...
InventoryItem(std::string Name, int Quantity);
...
};
class Product : public InventoryItem
{
...
Product();
Product(string Name, int Quantity, double Price);
...
};
class eProduct : public Product
{
...
eProduct(string Name, int Quantity, double Price, Condition condition);
...
};
#endif
答案 1 :(得分:1)
<强>问题强>
InventorySystem有一个名为BuildInventory的方法,它解析格式化的文本文件并动态地为eProduct对象分配一个指针数组。这不需要&#34;前向声明的构造函数&#34;宾语?
<强>答案强>
是的,这需要eProduct
的完整类定义以及从InventoryItem
派生的任何其他叶级别类。但是,这是在类的实现中。
类的定义仍然可以继续使用指向转发的声明类的指针。
答案 2 :(得分:1)
前向声明允许您指定前向声明类型的指针和引用,并且还使用函数声明中的类型(在返回类型和参数类型中)。确实,前向声明不允许您实际实例化该类型,例如作为局部变量或类属性,因为它还不是一个完整的类型(它被称为不完整类型),但如果不是必需的,你应该能够使它工作。
如果需要在函数体内处理类型的实例化,那么这也是完全可行的,前提是在完全定义了依赖类型之后定义了实际的函数体。这通常通过将类定义和函数实现分成两个单独的源文件来完成,即标题(.h
或.hpp
)和代码(.c
或.cpp
)。在实际进入代码之前,代码文件需要包含它们所依赖的所有头文件。
请参阅When can I use a forward declaration?,了解使用前向声明可以做什么和不做什么的绝佳摘要。