簡體   English   中英

如何創建 typedef 結構的前向聲明

[英]how to create a forward declaration of a typedef struct

我有 1 個 .h 文件test.h包含一個類。 在這個類中有一個私有方法返回一個指向我不想“公開”的類型的指針,但我希望能夠在其他源文件中包含這個test.h文件。

通常,在 .h 文件中使用前向聲明很容易:

class Foo;

但問題是這種類型來自一個我無法更改的 C 文件(因為它是我沒有維護的其他人的代碼)並且它是一個typedef

所以基本上我的test.cpp是:

// this type comes from a C file, cannot be changed to struct or class
typedef struct 
{
   int x;
} Foo;

#include "test.h"

static Foo foo;

Foo *Test::private_function()
{
  foo.x = 12;
  return &foo;
}

int Test::compute()
{
   auto *local_foo = private_function();
   return local_foo->x;
}

我的test.h文件是:

#pragma once

struct Foo;

class Test
{
public:
  Test() {}
  int compute();
private:
  Foo *private_function();
};

試圖編譯失敗:

>g++ -std=c++11 -c test.cpp
In file included from test.cpp:10:0:
test.h:3:8: error: using typedef-name 'Foo' after 'struct'
test.cpp:7:3: note: 'Foo' has a previous declaration here

目前我的解決方法是返回void *並來回執行static_cast ,但我沒有找到最佳方法。 有更好的解決方案嗎?

(我已經檢查了 C++ 中 typedef 的前向聲明,但我測試了解決方案,它們似乎不適用於我的情況,也許我想要做的更簡單/不同 - 我只有一個 .h 和 .cpp - 或只是不可能)

返回這個:

//#include "SecretFoo.h"
struct SecretFoo {
  uintptr_t handle;
};

//#include "SecretFooImpl.h"
#include "SecretFoo.h"
#include "Foo.h" // definition of typedef struct {int x;} Foo;
Foo* Crack( SecretFoo foo ) {
  return reinterpret_cast<Foo*>(foo.handle);
}
SecretFoo Encase( Foo* foo ) {
  return {reinterpret_cast<uintptr_t>(foo)};
}

現在我們得到:

#include "SecretFooImpl.h"
static Foo foo;

SecretFoo Test::private_function()
{
  foo.x = 12;
  return Encase(&foo);
}

int Test::compute()
{
   auto *local_foo = Crack(private_function());
   return local_foo->x;
}

並在您的標題中:

#pragma once
#include "SecretFoo.h"

class Test
{
public:
  Test() {}
  int compute();
private:
  SecretFoo private_function();
};

這歸結為相同的二進制代碼,但SecretFoo和成對的Crack / Encase函數提供了一種比void*更安全的轉換。


這種技術有時用於 C 世界。 SecretFoo是一種句柄; 一個不透明的類似指針的結構。 在這種情況下,其中的數據( uintptr_t handle )只是一個uintptr_t handle指針; 但它可以是指向指針表或其他任何內容的指針。 CrackEncase方法是允許訪問/創建SecretFoo的唯一方法。

不幸的是,typedef 不能被預先聲明。

一個常見的解決方法是擁有一個從 C 結構繼承的 C++ 類,由其 typedef 引用,您可以向前聲明它。 這將需要一些代碼更改,但它們應該是最小的。

(代表https://stackoverflow.com/users/3943312/sam-varshavchik發表評論)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM