在 C++ 中跨类使用结构

Posted

技术标签:

【中文标题】在 C++ 中跨类使用结构【英文标题】:Using a struct across classes in c++ 【发布时间】:2015-03-22 13:51:58 【问题描述】:

我对 c++ 还是很陌生,所以请允许! 本质上,我在头文件中为我的一个充满字符串的类创建了一个结构。

typedef struct details
        string name;
        string address;
details;

我不仅希望在属于标头的 cpp 文件中使用此结构,而且还希望在其他类中使用此结构。例如,我想在另一个头文件中创建这个结构的向量。

private:
vector <details> foo;

我也想在main中使用struct

details d;
d.name = "hi";
d.address = "hello";

但是,当我目前尝试执行此操作时,我会收到诸如

之类的错误
error: 'details' was not declared in this scope
     vector <details> foo;

error: template argument 1 is invalid
     vector <details> foo;

有没有人有类似的问题可以提供我可以做些什么来解决这个问题?非常感谢。

编辑以演示代码

class1.h

#include "class2.h"

struct trans1
    string name;
;
class class1 

private:
    vector <trans2> t2;

public:
    class1();
;

class2.h

#include "class1.h"

struct trans2
    string type;
;

class class2

private:
    vector <trans1> t1;

public:
    class2();
;

错误日志:

In file included from class1.h:3:0,
                 from class1.cpp:1:
class2.h:21:13: error: 'trans1' was not declared in this scope
     vector <trans1> t1;
             ^
class2.h:21:19: error: template argument 1 is invalid
     vector <trans1> t1;
                   ^
class2.h:21:19: error: template argument 2 is invalid

我知道这在现实世界的应用程序中是荒谬的代码,但这是我可以演示的最简单的方法

【问题讨论】:

您必须在每个引用该结构的 cpp 模块中包含此标头。 请提供SSCCE。 我在上面添加了代码 【参考方案1】:

您必须在使用它的任何地方包含包含struct 定义的头文件。

您不必这样做的唯一情况是您只声明引用或指向它的指针;在这种情况下,您只需转发声明即可:

struct details;

在 C++ 中你也可以声明它:

struct details
    std::string name;
    std::string address;
;

真的不需要typedef

【讨论】:

@πάνταῥεῖ > 唯一不需要的情况是你只声明引用或指向它的指针;在这种情况下,您可以转发声明它 @Jefffrey:unique_ptr 也是。但不是 auto_ptr,例如。【参考方案2】:

details.h

#include <string>

#ifndef DETAILS_H
#define DETAILS_H

struct details 
  std::string name;
  std::string address;
;

#endif

details.cpp

#include "details.h"
//insert implementation here

other_header.cpp

#include "details.h"
#include <vector>

std::vector<details> main_use;
//whatever else here

这应该可行。

编辑

如果你想在另一个类中使用它:

my_class.h

#include "details.h"
#include <vector>

#ifndef MYCLASS_H
#define MYCLASS_H

class myClass 
std::vector<details> class_use;
//insert stuff here

;

#endif

编辑 2

我很不确定你为什么要在类中定义结构——这有点令人困惑。如果是的话,我会这样做。请注意#ifndef ... #define ... #endif 模式非常重要。包含包含自身的标头也是一个坏主意。我会按以下方式组织您的代码(如您所愿):

trans.h

#ifndef TRANS_H 
#define TRANS_H

#include <string>
struct trans1 
   std::string name;
;

struct trans2 
   std::string type;
;

#endif

class1.h

 #ifndef CLASS1_H
 #define CLASS1_H

 #include "trans.h"
 #include <vector>

 class Class1 
   public:
     Class1();
   private:
     std::vector<trans2> t2;
 ;

 #endif

class2.h

 #ifndef CLASS2_H
 #define CLASS2_H

 #include "trans.h"
 #include <vector>

 class Class2 
   public:
     Class2();
   private:
     std::vector<trans1> t1;
 ;

 #endif

现在它的组织方式,您可以使用 trans 结构 #include "trans.h"'ing 在 main 中,同时消除循环包含。希望这会有所帮助。

你会发现下面的 main.cc 现在编译没有错误了。

main.cc

#include<iostream>
#include "class1.h"
#include "class2.h"
#include "trans.h"

int main()

    std::cout << "Hello, World!" << std::endl;

    return 0;


erip

【讨论】:

我已经包含了头文件,但收到了一个不同的错误:在 class.h:3:0, library.h:22:13 中包含的文件中:错误:'newClass' 未在这个作用域向量 nC; 所以同样的错误,但这次是一个类。我已经在每个班级中包含了所有标题。我不确定我哪里出错了。 你说你需要一个结构向量,而不是一个类向量。我很困惑。 是的,我也有一个类型为 class 的向量,即使头文件位于正确的位置,也会引发相同的错误。 发布在编辑中重新创建此错误所需的最少代码。我不明白。【参考方案3】:

c++中的结构体定义是这样的

 #include <string>

 struct details
    std::string name;
    std::string address;
 ;

并且必须在代码中的其他地方使用之前看到。假设你将上面的声明放在头文件details.hpp 中,你应该有以下使用它

 #include <vector>
 #include "details.hpp"

 // Some context

 std::vector<details> vdetails;

在某些情况下,当 details 结构成员实际上没有被访问时,您也可以使用前向声明作为

 struct details;

而不是包含完整的结构声明。然后可以使用它,在进一步的声明中声明 details* 指针或 details&amp; 引用,只要它们没有被取消引用。

【讨论】:

以上是关于在 C++ 中跨类使用结构的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何配置我的应用以跨类保留 Firebase 用户数据?

如何在 C++ 中跨多个源文件共享变量?

程序在 Windows 中跨 DLL 边界使用嵌入式 Python/C++ 代码崩溃

C ++跨类访问基对象向量中的派生对象的引用

如何在 R 中跨多个字段创建简单的交叉表

容器中跨主机的网络方案-Calico