标签: forward-declaration

前方声明不会做

下面是代码的两个片段(准备编译).在第一个片段中,我只使用结构的前向声明,同时从Guest类删除指向此结构的指针,不调用Guest类.
在第二个片段中,而不是前向声明我使用基本工作中的删除使用此Guest类的完整定义.
为什么?为什么会有所作为?是不是前向声明假设只是编译器的一个注释,说这个类/结构的定义在其他地方?
我很惊讶它只是不直观地工作.

//First just forward dclr  
#include "stdafx.h"
#include <iostream>
using std::cout;

struct Guest;

struct Base
{
    Guest* ptr_;
    Base(Guest* ptr):ptr_(ptr)
    {
        cout << "Base\n";
    }
    ~Base()
    {
        cout << "~Base\n";
        delete ptr_;
    }
};

struct Guest
{
    Guest()
    {
        cout << "Guest\n";
        throw std::exception();
    }
    Guest(int)
    {
        cout << "Guest(int)\n";
    }
    ~Guest()
    {
        cout << "~Guest\n";
    }
};

struct MyClass : Base
{
    Guest g;
    MyClass(Guest* g):Base(g)
    {
        cout << "MyClass\n";

    }
    ~MyClass()
    {
        cout << "~MyClass\n"; …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration

6
推荐指数
2
解决办法
3887
查看次数

即使使用@protocol,Xcode也会警告缺少协议定义

由于我最近有一个导入循环,我将所有#import语句(关于我自己的文件)从标题移动到相应的.m-file中.我还添加了@class@protocol前瞻性声明,以安抚编译器.但是,我仍然听到他的警告:

Cannot find the protocol definition for 'MyCustomDelegate'.
Run Code Online (Sandbox Code Playgroud)

正如我所说,@protocol MyCustomDelegate之前我在@interface-Block中使用它.有趣的是,只有在另一个文件中声明相应的委托(其标头在.m-file中导入)时,才会出现此警告.

我读到一个解决方案是在单独的头文件中声明委托,并直接在实现委托的类的头中导入该文件.这真的是要走的路吗?还有其他解决方案吗?我认为那些代表已经充分夸大了我们的代码,现在我应该继续甚至为它声明一个自己的文件?

小样本代码可以更好地说明问题:

NewFooController.h

#import <UIKit/UIKit.h>

@protocol NewFooControllerDelegate;

@interface NewFooController : UITableViewController
  @property (nonatomic, weak) id<NewFooControllerDelegate> delegate;
@end

@protocol NewFooControllerDelegate
@end
Run Code Online (Sandbox Code Playgroud)

HomeTableViewController.h

#import <UIKit/UIKit.h>
@protocol NewFooControllerDelegate;

// warning points to line below
@interface HomeTableViewController : UITableViewController <NewFooControllerDelegate>
@end
Run Code Online (Sandbox Code Playgroud)

HomeTableViewController.m

#import "HomeTableViewController.h"
#import "NewFooController.h"
@implementation HomeTableViewController
@end
Run Code Online (Sandbox Code Playgroud)

xcode protocols objective-c forward-declaration

6
推荐指数
1
解决办法
1779
查看次数

命名空间中的C++前向声明和友谊

根据7.3.1.2 C++标准ISO/IEC 14882:2003(E)中的命名空间成员定义

首先在名称空间中声明的每个名称都是该名称空间的成员.如果非本地类中的友元声明首先声明一个类或函数(这意味着该类或函数的名称是不合格的),那么友元类或函数是最内层封闭命名空间的成员.

// Assume f and g have not yet been defined.
void h(int);
template <class T> void f2(T);
namespace A {
   class X {
   friend void f(X);  //  A::f(X) is a friend
      class Y {
         friend void g();  //  A::g is a friend
         friend void h(int);  //  A::h is a friend
         //  ::h not considered
         friend void f2<>(int);  //  ::f2<>(int) is a friend
      };
   };
   //  A::f, A::g and A::h are not visible here
   X x;
   void …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces access-control friend forward-declaration

6
推荐指数
1
解决办法
340
查看次数

两个类相互引用

假设有两个类,它们需要彼此:容器项目.类容器创建类项的实例.类项的每个实例都包含一个类容器的实例,只需要调用类容器的方法method_called_by_item.类容器需要查看类项的所有字段.

问题是前向声明:我想在item.h中有一个前向声明,这样类可以有一个容器作为字段并调用方法method_called_by_item.我怎么做?

容器,用于创建项目.

// container.h
#ifndef CONTAINER_H
#define CONTAINER_H

#include "item.h"

class container{

public:
  item * create_item();
  void method_called_by_item(item * i);
};

#endif //CONTAINER_H
Run Code Online (Sandbox Code Playgroud)

实施:

// container.cpp
#include "container.h"

item * container::create_item(){
  return new item(this);
}

void container::method_called_by_item(item * i){
  // do stuff with item
}
Run Code Online (Sandbox Code Playgroud)

,需要调用一个容器 …

c++ forward-declaration

6
推荐指数
2
解决办法
7006
查看次数

SBCL前瞻性声明:可能吗?

我在SBCL中编写了一些代码,当我将文件加载到REPL中时,我的函数的顺序一直会导致出现以下类型的警告:

;caught STYLE-WARNING:
    undefined function: FOO
Run Code Online (Sandbox Code Playgroud)

FOO函数的符号在哪里.这纯粹是因为他们是如何在我的文件排序,作为函数FOO 定义,只是没有抛出这一警告的代码部分之前.

现在,在Clojure中,我熟悉的是Lisp,我有一个declare表单,它允许我做出前瞻性声明以避免这种问题.SBCL/Common Lisp总体上有类似的东西吗?

sbcl forward-declaration

6
推荐指数
2
解决办法
784
查看次数

MatrixXd 和 VectorXd 类型的前向声明?

也许有人知道,是否可以在特征中转发声明类型MatrixXd & VectorXd

\n\n

编译时,我收到以下错误:

\n\n

/usr/include/eigen3/Eigen/src/Core/Matrix.h:372:34: 错误:声明冲突 \xe2\x80\x98typedef 类 Eigen::Matrix Eigen::MatrixXd\xe2\x80\x99

\n\n

typedef Matrix Matrix##SizeSuffix##TypeSuffix;

\n\n

SIMP.h

\n\n
#ifndef SIMP_H\n#define SIMP_H\n\n\nnamespace Eigen\n{\n    class MatrixXd;\n    class VectorXd;\n}\n\nclass SIMP {\npublic:\n    SIMP(Eigen::MatrixXd * gsm, Eigen::VectorXd * displ);\n    SIMP ( const SIMP& other ) = delete;\n    ~SIMP(){}\n    SIMP& operator= ( const SIMP& other ) = delete;\n    bool operator== ( const SIMP& other ) = delete;\n\n\nprivate:      \n    Eigen::MatrixXd * m_gsm;\n    Eigen::VectorXd * m_displ;\n\n};\n\n#endif // SIMP_H\n
Run Code Online (Sandbox Code Playgroud)\n\n

SIMP.cpp

\n\n
#include "SIMP.h"\n#include <Eigen/Core>\nSIMP::SIMP( Eigen::MatrixXd …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration eigen

6
推荐指数
1
解决办法
2273
查看次数

使用STL容器转发对象的声明

请考虑以下代码段,其中第一行仅用作前向声明

 class A;
Run Code Online (Sandbox Code Playgroud)

然后定义新类

class B
{
 vector<A> Av;  //line 1
 map<int, A> Am;  //line 2
 pair<int, A> Ap; //line 3
};
Run Code Online (Sandbox Code Playgroud)

第1行和第2行似乎没有前向声明(这可能告诉我那些容器使用指针类型的实现),其中第3行似乎不在VS2012上编译.

我的问题是标准或特定于我正在使用的编译器所规定的行为?

谢谢

c++ stl forward-declaration std-pair visual-studio-2012

6
推荐指数
2
解决办法
1366
查看次数

返回函数类型的前向声明

正如这个答案所暗示的那样,我知道允许在函数声明中使用不完整类型作为返回值.所以我写了下面的代码:

Obj.h

class Obj {
    int x;
};
Run Code Online (Sandbox Code Playgroud)

FH

class Obj;
Obj f();
Run Code Online (Sandbox Code Playgroud)

f.cpp

#include "Obj.h"

Obj f() {
    return Obj();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "f.h"
int main() {
    f();
    return 0;
};
Run Code Online (Sandbox Code Playgroud)

使用以下编译器编译此代码:

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)

使用以下编译命令:

g++ *.cpp
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

main.cpp: In function 'int main()':
main.cpp:4:7: error: invalid use of incomplete type 'class Obj'
     f();
       ^
f.h:1:7: error: forward declaration of 'class Obj'
 class Obj;
       ^
Run Code Online (Sandbox Code Playgroud)

因此编译器不允许在函数声明中使用不完整类型作为返回值.解释是什么?

c++ forward-declaration

6
推荐指数
2
解决办法
2296
查看次数

我在理解[basic.scope.pdecl] / 7时遇到了一些困难

[basic.scope.pdecl] / 7

首先elaborated-type-specifier中声明的类的声明要点如下:

(7.1)声明形式

          class-key attribute-specifier-seq opt 标识符 ;

         的识别符被声明为一个类名称在包含声明的范围,否则

(7.2)用于阐述型说明符的形式的

          类键 标识符

         如果在命名空间范围内定义的函数的decl-specifier-seqparameter-declaration-clause中使用了elaborated-type-specifier,则标识符将在包含该声明的命名空间中声明为类名;否则,除作为好友声明外,标识符在包含该声明的最小名称空间或块范围中声明。[?注意:这些规则也适用于模板。-?end note?] [?注:其他形式的 elaborated-type-specifier不会声明新名称,因此必须引用现有的type-name
         。请参阅[basic.lookup.elab]和[dcl.type.elab]。-?尾注?]

考虑上面的情况(7.2),其中在命名空间范围中定义的函数的参数声明子句decl-specifier-seq中使用了elaborated-type-specifier。这个精巧的类型说明符必须是该类在其命名空间中的第一个声明,这一事实如何与之相协调?

考虑下面的示例(demo):

档案prog.cc

struct S;
extern S s;
int S;
void f(struct S&);     // The elaborated-type-specififer `struct S` is not
                       // the first …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration language-lawyer

6
推荐指数
1
解决办法
192
查看次数

Python:数据类的循环依赖/前向变量声明?

所以,我在一个文件中有这两个数据类:

@dataclass
class A:
    children: List[B]

@dataclass
class B:
    parent: A
Run Code Online (Sandbox Code Playgroud)

,这可以通过使用该__future__.annotations功能来实现。

然后我有另外两个文件,每个文件都有一堆对于我的项目来说是静态的每种类型的对象。

文件objects_A

import objects_B

obj_a1 = A(
    children=[
        objects_B.obj_b1,
        objects_B.obj_b2
    ]
)
Run Code Online (Sandbox Code Playgroud)

文件objects_B

import objects_A

obj_b1 = B(
    parent=objects_A.obj_a1
)

obj_b2 = B(
    parent=objects_A.obj_a1
)
Run Code Online (Sandbox Code Playgroud)

显然,文件之间存在循环依赖问题,但即使它们位于同一个文件中,它也不起作用,因为一种类型的变量依赖于另一种类型的变量才能成功。
初始化B内部对象obj_a1也不起作用,因为self这里没有概念。

目前,我设置parentNone(针对类型提示),然后循环进行设置obj_a1

for obj_b in obj_a1.children:
    obj_b.parent = obj_a1
Run Code Online (Sandbox Code Playgroud)

大家有什么好主意吗?
不知道它是否有帮助,但是这些对象是静态的(它们在这些声明之后不会改变)并且它们具有某种父子关系(正如您肯定已经注意到的那样)。
如果可能的话,我希望将每种类型的变量放在不同的文件中。

python forward-declaration circular-reference python-3.x python-dataclasses

6
推荐指数
1
解决办法
1544
查看次数