以下代码是否合法C++?
class Foo
{
class Bar;
void HaveADrink(Bar &bar);
void PayForDrinks(Bar &bar);
public:
void VisitABar(int drinks);
};
class Foo::Bar
{
public:
int countDrinks;
};
void Foo::HaveADrink(Bar &bar)
{
bar.countDrinks++;
}
void Foo::PayForDrinks(Bar &bar)
{
bar.countDrinks = 0;
}
void Foo::VisitABar(int drinks)
{
Bar bar;
for (int i=0; i<drinks; i++) HaveADrink(bar);
PayForDrinks(bar);
}
Run Code Online (Sandbox Code Playgroud)
Visual C++和GCC都接受它,但是代码对我来说似乎有些奇怪,我不愿意让它被未来的编译器拒绝.
尽管如此,这种模式似乎对减少编译时依赖性很有用 - 我经常使用它来声明用于传递一些"上下文"(一堆变量)的结构,这些结构在一些函数之间共享,这些函数都位于同一个cpp中文件,这样我就不必将"上下文"定义引入公共接口.
我有一些C代码,我必须移植到C++.代码有一个结构
struct A {
...
struct A * myPtr;
}
Run Code Online (Sandbox Code Playgroud)
现在声明和初始化两个全局数组,如下所示:
//Forward declaration of Unit
struct A Unit[10];
struct A* ptrUnit[2] = { Unit, Unit+7 };
struct A Unit[10] = { { .., &ptrUnit[0] },
... };
Run Code Online (Sandbox Code Playgroud)
现在虽然这在C中运行良好,但它在C++中给出了一个错误(变量重新声明).是不是允许变量在C++中进行前向声明?
我知道我能做到
class Foo;
Run Code Online (Sandbox Code Playgroud)
可能
struct Bar;
Run Code Online (Sandbox Code Playgroud)
和全球职能
bool IsValid(int iVal);
Run Code Online (Sandbox Code Playgroud)
键入的枚举怎么样?在未申报的课程中输入的枚举怎么样?具有未声明的类的函数怎么样?那个未申报的课程中的静态成员怎么样?在未知的命名空间中这些怎么办?我错过了任何可以向前宣布的东西吗?
有一个带有隐式参数的模板类声明:
List.h
template <typename Item, const bool attribute = true>
class List: public OList <item, attribute>
{
public:
List() : OList<Item, attribute> () {}
....
};
Run Code Online (Sandbox Code Playgroud)
我尝试在不同的头文件中使用fllowing forward声明:
Analysis.h
template <typename T, const bool attribute = true>
class List;
Run Code Online (Sandbox Code Playgroud)
但是G ++显示了这个错误:
List.h:28: error: redefinition of default argument for `bool attribute'
Analysis.h:43: error: original definition appeared here
Run Code Online (Sandbox Code Playgroud)
如果我使用没有隐式参数的前向声明
template <typename T, const bool attribute>
class List;
Run Code Online (Sandbox Code Playgroud)
编译器不接受这种结构
Analysis.h
void function (List <Object> *list)
{
}
Run Code Online (Sandbox Code Playgroud)
并显示以下错误(即不接受隐含值):
Analysis.h:55: error: wrong number of …Run Code Online (Sandbox Code Playgroud) 我正在尝试对我通过IB设置的对象做一些动画.我正在向我的.h添加一个前向声明,如下所示:
@class MySpecialClass;
Run Code Online (Sandbox Code Playgroud)
然后设置如下属性:
@property (nonatomic, retain) IBOutlet MySpecialClass *specialClass;
Run Code Online (Sandbox Code Playgroud)
我希望能够隐藏specialClass使用setAlpha,但我在尝试编译时从xcode得到以下错误.
Receiver type 'MySpecialClass' for instance message is a forward declaration.
Run Code Online (Sandbox Code Playgroud)
我是否需要导入我的课程而不是前瞻性声明?如果我不需要,我不想输入任何不必要的东西.
我在头文件中有以下声明:
struct my_struct;
int func(struct my_struct* s); // Passing struct my_struct*
Run Code Online (Sandbox Code Playgroud)
如果没有前向声明,编译器显然会出现此错误:
error: 'struct my_struct' declared inside parameter list
但是,如果我用my_structtypedef 替换前向声明,并相应地更新函数声明,它编译正常:
typedef struct my_struct my_struct_t;
int func(mystruct_t* s); // Passing my_struct_t*
Run Code Online (Sandbox Code Playgroud)
奇怪的是,如果我保留typedef,但使用原始声明my_struct,它也会编译:
typedef struct my_struct my_struct_t;
int func(struct my_struct* s); // Passing struct my_struct*
Run Code Online (Sandbox Code Playgroud)
有人注意到了吗?这种行为是副作用吗?
namespace CounterNameSpace {
int upperbound;
int lowerbound;
using namespace NS;//Error
}
namespace NS {
int i;
}
// ...
namespace NS {
int j;
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,它显示了一个错误.错误C2871:'NS':具有此名称的命名空间不存在我知道如果我在解决反向空间问题之前定义NS.但只是想知道在c ++中是否存在任何类似命名空间的前向声明的东西.因此,在没有在counternamespace之前定义NS的情况下,上述问题将得到解决.请帮忙 .
我写的代码:
struct A;
struct B;
struct A
{
int v;
int f(B b)
{
return b.v;
}
};
struct B
{
int v;
int f(A a)
{
return a.v;
}
};
Run Code Online (Sandbox Code Playgroud)
编译消息:
|In member function 'int A::f(B)':|
11|error: 'b' has incomplete type|
7|error: forward declaration of 'struct B'|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|
Run Code Online (Sandbox Code Playgroud)
我知道,为什么代码不正确,但我不知道如何实现两个可以相互访问的结构.有什么优雅的方式吗?提前致谢.
我知道typedef不能在C++中进行前向声明,但我想知道什么是以下问题的最佳解决方案.我有一个头文件,声明MyClass如下:
#include <TemplateClassHeaders>
struct MyStruct
{
// ...
}
typedef Really::Long::TemplateClassName<MyStruct> MyClass;
Run Code Online (Sandbox Code Playgroud)
MyClass在许多地方使用,但大部分只是作为指针通过Qt信号槽机制.前向声明将是所有需要的,但因为MyClass是一个不起作用的typedef.有没有办法避免将myclass.h添加到使用指针的每个标头MyClass?
一个可编辑的例子:
main.cpp中
#include "test.h"
int main(int argc, char* argv[]) {
auto myPtr = std::unique_ptr<MyClass>(getMyPtr());
}
Run Code Online (Sandbox Code Playgroud)
test.h
#ifndef TEST_H
#define TEST_H
#include <memory>
class MyClass;
extern template class std::unique_ptr<MyClass>;
MyClass* getMyPtr();
#endif
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
#include "test.h"
class MyClass {};
template class std::unique_ptr<MyClass>;
MyClass* getMyPtr() { return new MyClass; }
Run Code Online (Sandbox Code Playgroud)
g ++ 4.9.2抱怨
In file included from c:/devel/mingw32/i686-w64-mingw32/include/c++/memory:81:0,
from main.cpp:4:
c:/devel/mingw32/i686-w64-mingw32/include/c++/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = MyClass]':
c:/devel/mingw32/i686-w64-mingw32/include/c++/bits/unique_ptr.h:236:16: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = MyClass; _Dp = std::default_delete<MyClass>]' …Run Code Online (Sandbox Code Playgroud) c++ ×8
templates ×3
c ×2
struct ×2
typedef ×2
arrays ×1
c++11 ×1
class ×1
definition ×1
dependencies ×1
implicit ×1
import ×1
ios ×1
namespaces ×1
parameters ×1
syntax ×1
xcode ×1