在 c++ 中跨类使用结构

Using a struct across classes in c++

本文关键字:结构 c++      更新时间:2023-10-16

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

typedef struct details{
        string name;
        string address;
}details;

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

private:
vector <details> foo;

我还想在主中使用结构

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;

没有人有类似的问题,他们可以在现场提供我可以做些什么来解决这个问题?多谢。

编辑以演示代码

类1.h

#include "class2.h"
struct trans1{
    string name;
};
class class1 {
private:
    vector <trans2> t2;
public:
    class1();
};

类2.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

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

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

唯一不必这样做的情况是,当你只声明引用或指向它的指针时;在这种情况下,你可以用以下命令转发声明它:

struct details;

同样在C++中,您可以通过以下方式声明它:

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

真的不需要typedef.

详情.h

#include <string>
#ifndef DETAILS_H
#define DETAILS_H
struct details {
  std::string name;
  std::string address;
};
#endif

详情.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模式非常重要。包含包含自身的标头也是一个坏主意。我会通过以下方式组织您的代码(就像您一样(:

跨 H

#ifndef TRANS_H 
#define TRANS_H
#include <string>
struct trans1 {
   std::string name;
};
struct trans2 {
   std::string type;
};
#endif

类1.h

 #ifndef CLASS1_H
 #define CLASS1_H
 #include "trans.h"
 #include <vector>
 class Class1 {
   public:
     Class1();
   private:
     std::vector<trans2> t2;
 };
 #endif

类2.h

 #ifndef CLASS2_H
 #define CLASS2_H
 #include "trans.h"
 #include <vector>
 class Class2 {
   public:
     Class2();
   private:
     std::vector<trans1> t1;
 };
 #endif

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

您会发现下面的 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;
}

埃里普

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&引用,只要没有取消引用它们。