【问题标题】:Header file and namespace confusion头文件和命名空间混淆
【发布时间】:2013-08-26 02:07:47
【问题描述】:

我正在尝试将专辑对象从 main 发送到另一个 .cpp 文件中的函数,但编译时出现错误:

我从 main 创建了一个 Album 对象,然后尝试将它传递给菜单函数,如下所示:

Model::Album album("TestAlbum");
View::Menu m;
m.startMenu(album);

我的菜单类:

#include "stdio.h"
#include "Menu.hpp"
#include "AlbumOps.hpp"
#include "Album.hpp"
#include <iostream>
using namespace std;

namespace View
{
void Menu::startMenu(Model::Album inAlbum) //compile errors happen here
    {
    int option = 1;
    while (option!=5)
        {
        cout << "1. Add image to album\n";
        cout << "2. Remove image from album\n";
        cout << "3. List all images in album\n";
        cout << "4. View image in album\n";
        cout << "5. Quit\n";
//and so on

当我尝试编译它时,我在 void Menu::startMenu(Model::Album inAlbum) 行中遇到错误

“模型”尚未声明

Model 是我使用的命名空间。我认为包含 Album.hpp 可以解决这个问题,但它没有,我不知道如何解决这个问题。

编辑:Menu 是一个类,这里​​是我的 Menu.hpp:

#ifndef MENU_H //"Header guard"
#define MENU_H

namespace View
{
class Menu
    {
    public:
    void startMenu(Model::Album inAlbum);
    };
}
#endif

还有我的 Album.hpp:

#ifndef ALBUM_H
#define ALBUM_H

#include <string>
#include <vector>
#include "Image.hpp"

namespace Model{
class Album
{
  private:
    std::vector<Image*> imageList;
    std::string albumName;      


  public:
    Album(std::string);

    /****Setters****/
    void setAlbumName(std::string);
    void addImage(Image);

    /****Getters****/
    Image getImage(int);
    std::string getAlbumName();
    int getListLength();
};
}
#endif

【问题讨论】:

  • 什么是“菜单”?它在哪里声明?它是如何声明的?
  • 问题很可能出在Album.hpp 或其他标题之一中。
  • 把#include "Album.hpp" 放在#include "Menu.hpp" 上面
  • 谢谢,我刚刚尝试将专辑放在首位,但仍然出现错误。
  • “View”不知道“Album”。像 JackyZhu 建议的那样,将“Album.hpp”移到“Menu.hpp”之前。

标签: c++ header namespaces


【解决方案1】:

您的Menu.hpp 缺少一些声明。标头应该可以自行编译,而无需在它们之前包含其他标头。所以如果你不确定你应该总是尝试编译这样的东西:

#include "Menu.hpp"

int main() {
}

如果不能编译,则需要在header中添加includes或declarations。

现在 Menu.hpp 中缺少的是 Album 类的声明。仅包含专辑标题会过度杀伤并导致循环包含,因此前向声明是正确的做法:

#ifndef MENU_H //"Header guard"
#define MENU_H

//forward declaration of Album:
namespace Model {
  class Album;
}

namespace View
{
class Menu
    {
    public:
    void startMenu(Model::Album inAlbum);
    };
}
#endif 

在您的相册标题中,图片标题的包含太多。前向声明就足够了,因为您实际上并不使用 Image,您只使用指向 Image 的指针并将其类型声明为某些函数的返回和参数类型。不过,您可能需要在 Album.cpp 中包含图像标题。

有关包含和转发声明的更多信息,请阅读this excellent GOTW article from Herb Sutter

【讨论】:

    猜你喜欢
    • 2012-03-29
    • 1970-01-01
    • 2012-09-06
    • 2014-04-14
    • 2011-12-28
    • 2022-06-17
    • 1970-01-01
    • 2023-01-30
    • 2023-03-14
    相关资源
    最近更新 更多