在我的C++项目中何时必须使用#include "myclass.h"头文件的includes()?我什么时候必须使用class(class CMyClass;)的前向声明?
是否可以将前向声明的类的成员函数声明为朋友?我正在尝试执行以下操作:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
// OK, but provides too broad access:
friend class BigComplicatedClass;
// ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
Run Code Online (Sandbox Code Playgroud)
因此,目标是(i)将友元声明限制为单个方法,以及(ii)不包括复杂类的定义以减少编译时间.
一种方法可能是添加一个充当中间人的类:
// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
// (...)
friend class BigComplicatedClass_Helper;
};
// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
Run Code Online (Sandbox Code Playgroud)
然而,这似乎有点笨拙...所以我认为必须有一个更好的解决方案!
我的问题:
有两个班,A班和B班,所以我得到了Ah和A.cpp以及Bh和B.cpp.需要知道B和B需要知道A.我用以下方式解决了它(我不知道为什么它必须如此......)
啊:
#include "B.h"
class A{ ...
Run Code Online (Sandbox Code Playgroud)
A.cpp:
#include "A.h"
Run Code Online (Sandbox Code Playgroud)
BH:
#include "A.h"
class A; // forward declaration
class B { ...
Run Code Online (Sandbox Code Playgroud)
B.cpp:
#include "B.h"
Run Code Online (Sandbox Code Playgroud)
我使用了一个前向声明并且它有效.
问题是,两个类都需要在命名空间"ui"中.或者至少我认为这是意思:
啊:
#include "B.h"
namespace ui{
class A;
}
class A{ ...
Run Code Online (Sandbox Code Playgroud)
BH:
#include "A.h"
namespace ui{
class B;
}
class B{ ...
Run Code Online (Sandbox Code Playgroud)
这不再起作用了.现在我需要做些什么来使命名空间和前向声明再次起作用?
两者都必须在此命名空间中.我正在使用Qt,需要使用"namespace ui {"等行.两个班级都需要相互了解.我已经尝试过这样做:
namespace ui{
class A;
class B;
}
Run Code Online (Sandbox Code Playgroud)
在两个标题中,但这不起作用......
顺便说一句:所有Header-Files也获得了"ifndef"机制.
我有以下代码:
#include <iostream>
using namespace std;
class CForward;
void func(CForward* frw) { delete frw; }
class CForward
{
public:
~CForward() { cout << "Forward" << endl; }
};
int main()
{
func(new CForward);
cin.get();
}
Run Code Online (Sandbox Code Playgroud)
我运行程序,它什么都没打印.
为什么?
在main中,我创建了new CFoward,并在func我删除它并将其称为析构函数.
似乎没有调用析构函数.为什么?无论如何这与前瞻性相关有关吗?
我的印象是C++中的所有内容必须在使用之前声明.
事实上,我记得读过这就是为什么auto在返回类型中使用C++ 0x无效的原因decltype:编译器在评估函数体之前必须知道声明的类型.
想象一下,当我注意到(经过很长一段时间)以下代码实际上完全合法时,我感到很惊讶:
[编辑:更改示例.]
class Foo
{
Foo(int x = y);
static const int y = 5;
};
Run Code Online (Sandbox Code Playgroud)
所以现在我不明白:
我正在尝试编译一个javac拒绝非法前向引用错误的Java类,其中违规引用是在引用字段之后的词法上.在显示相同行为时,尽可能地删除以下类:
java.util.concurrent.Callable并且许多用途Object仅用作占位符来删除不相关的代码片段.
public class Test {
static final Object foo = method(new java.util.concurrent.Callable<Object>() {
@Override
public Object call() throws Exception {
return bar;
}
});
static final Object bar = foo;
static Object method(Object binder) {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
使用时编译javac Test.java,javac打印以下错误消息:
Test.java:9: illegal forward reference
static final Object bar = foo;
^
Run Code Online (Sandbox Code Playgroud)
所以编译器抱怨bar声明引用的foo同时foo应该在bar声明的范围内.但是一旦删除了barin foo的声明的引用,例如通过将第5行更改return …
有这个代码:
class A;
template <class T>
void fun() {
A a;
}
class A {
public:
A() { }
};
int main() {
fun<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.5和g ++ 4.7编译时没有错误.但是clang ++ 3.2(trunk)给出了这个错误:
main.cpp:5:6: error: variable has incomplete type 'A'
A a;
^
main.cpp:1:7: note: forward declaration of 'A'
class A;
^
Run Code Online (Sandbox Code Playgroud)
根据C++标准,哪个编译器是正确的?
在State.h我有
enum class StateID : unsigned int;
Run Code Online (Sandbox Code Playgroud)
在State.cpp我有
enum class StateID : unsigned int
{
NullID = 0,
MainMenuID,
GamePlayID,
};
Run Code Online (Sandbox Code Playgroud)
问题是任何包含的类State.h都有前向声明,但我不能enum在任何cpp文件中使用任何值,除了States.cpp(定义它),比如StateID::MainMenuID.错误说......
/home/lee/Projects/SuddenAwakening/Source/Game.cpp:24:错误:'MainMenuID'不是'StateID'的成员
我正在运行LinuxMint15KDE,g ++ 4.7,我在其他部分使用c ++ 11功能,如nullptr,unique_ptr,ect ......,所以我不会忘记c ++ 11的编译器标志.
我正在学习用boost/asio编写代码.许多代码示例都使用了async_accept和bind的组合.在服务器代码中,我遇到了这样的事情:
class Tcp_server
{
public:
Tcp_server()
{
}
void start_accept(int a)
{
if(a>0)
{
cout<<a<<endl;
handle_accept(a-1);
}
}
void handle_accept(int a)
{
if(a>0)
{
cout<<a<<endl;
start_accept(a-1);
}
}
};
Run Code Online (Sandbox Code Playgroud)
如果我创建一个Tcp_server的实例并调用handle_accept或start accept,它就可以工作.但是,如果我删除Tcp_server类封装,编译器会抱怨"未声明handle_accept".我只是想知道编译器是否自动转发声明在同一个类中定义的所有函数.有谁能解释为什么?
c++ ×9
c++11 ×1
clang++ ×1
enum-class ×1
friend ×1
function ×1
g++ ×1
header-files ×1
include ×1
java ×1
javac ×1
namespaces ×1
templates ×1