前向声明并动态分配该声明类的指针数组?

时间:2015-02-09 03:55:57

标签: c++ forward-declaration

我一直在用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;
}

3 个答案:

答案 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?,了解使用前向声明可以做什么和不做什么的绝佳摘要。