Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;仅头文件项目-从不同程序集使用_C++_Visual Studio 2012_Linker_Compiler Errors - Fatal编程技术网

C++ C++;仅头文件项目-从不同程序集使用

C++ C++;仅头文件项目-从不同程序集使用,c++,visual-studio-2012,linker,compiler-errors,C++,Visual Studio 2012,Linker,Compiler Errors,我有一个项目,我不得不将.cpp/头文件分开,改为将定义合并到头文件中。最初我尝试将cpp文件的内容复制到头文件中,但我的ide-VS2012 express-将我发送到一个循环中,它说头文件包含它自己,因此当我删除include“class.h”时,它抱怨在class::functionname的情况下,无法识别该类。最终我决定在标题中定义定义,例如 class Thing { public: void func { code; } } 这解决了我在项目中的编译问题。问题是我有一个测

我有一个项目,我不得不将.cpp/头文件分开,改为将定义合并到头文件中。最初我尝试将cpp文件的内容复制到头文件中,但我的ide-VS2012 express-将我发送到一个循环中,它说头文件包含它自己,因此当我删除include“class.h”时,它抱怨在class::functionname的情况下,无法识别该类。最终我决定在标题中定义定义,例如

class Thing {
public:
   void func { code; } 
}
这解决了我在项目中的编译问题。问题是我有一个测试项目——WinUnit——我不能再访问这些函数了。该项目过去是一个静态库,并进行了相应的链接,但由于没有.cpp文件,该项目没有生成.lib。尝试更改为动态链接库,同样的问题-未生成dll。因此,我添加了一个项目引用,它似乎可以在我键入include“class.h”时识别出我的类文件

我的问题是它仍然没有编译类。它根本无法识别测试项目的.cpp文件中的类名。我甚至尝试将头文件添加到测试项目中,但仍然没有任何乐趣。我试着将附加的Include目录设置为指向头所在的位置-没有用

我怎样才能做到这一点

编辑: 仍然卡住了,所以我创建了一个SSCCE,它工作得很好,将测试项目指向附加的INclude目录中的header files目录,它工作得很好。虽然主项目编译得很好,但我注意到它有一个intellisense错误-标识符“ClassName”未定义。所有其他类别都承认其他类别。存在#include“className”。当我构建测试项目时,第一个错误与intellisense错误相关:错误1错误C2143:语法错误:缺少“;”在“*”之前

实际行是:ClassName*obj;-这是一个私有变量

测试项目中有629个错误-一些其他代码:c4430、c2061。我想这些都只是最初问题的副作用,与课程没有被认可有关…我迷路了,可能会退出并重新思考失败的原因


编辑:修复了intellisense错误,因此所有错误现在都在Testproject中-增加到826个错误。在包含头文件时查看它们,但不识别任何类名。错误代码:示例代码中的c2061、c2065、c2923等func是私有的,因为这是类内的默认访问权限。也许您想定义public函数,以便测试代码和类的其他客户端可以访问它

如果您只是将函数定义放在标题中,那么还必须将其内联。可以显式(对于自由函数和完全专用的函数模板定义),也可以隐式(即在类定义中定义类方法)

您是对的,库不再生成任何编译输出,即您不必链接库或dll文件。因此,在使用库的任何项目中,包括测试项目,您不再需要指定要与该项目链接的库。毕竟,这是只包含头的库的原因之一:它们在编译时被完全包含(与链接时相反)

如果您的测试项目以前编译过,那么它也应该在修改后编译,前提是您之前测试过所有库类,并且没有对名称空间结构进行任何更改

如果没有一个错误和从编译器中得到的正确错误,人们只能猜测您可能会陷入的其他陷阱

编辑:想到的一件事是循环包含,即使源到头的重构已正确完成,也会导致问题。如果您有这些类,那么您必须打破依赖关系,或者将两个类放在同一个头中,在两个类定义之后提供方法定义(记住显式内联声明方法定义)

Edit2:循环包含的简单示例:类a和类B都有一个调用另一个类的方法的方法。因此,每个类方法的定义都需要另一个类方法的声明,即,另一个类的前向声明是不够的。在正常情况下,源将同时包括头和完成。在仅标题的情况下,编译器将如下所示:

class A {
  B* b_;
public:
  A(B* b) : b_(b) {}
  void foo() {b_->meow();}
};

class B {
public:
  void bar() { A a(this); a.foo(); }
  void meow() { /* ... */}
};
编译器将抱怨B的使用和对
B::meow()
的调用。前者可以通过向前声明B来解决,后者不能。先定义B没有帮助,A和
A::foo()
也会有同样的问题。因此,解决方案必须如下所示:

class A {
  B* b_;
public:
  A(B* b) : b_(b) {}
  void foo();   //1
};

class B {
public:
  void bar() { A a(this); a.foo(); }
  void meow() { /* ... */}
};

inline void A::foo() {b_->meow();} //2
class B_Interface
{
public: 
  virtual void meow() = 0;
};

class A {
  B_Interface* b_;
public:
  A(B_Interface* b) : b_(b) {}
  void foo() {b_->meow();} //OK this time
};

class B : public B_Interface {
public:
  void bar() { A a(this); a.foo(); }
  virtual void meow() { /* ... */}
};
依赖于第二类的第一类方法的定义将延迟到第二类定义之后。因为A需要B,B需要A,所以在一个只有头的库中,在两个不同的头中分离这种混合的类定义是没有意义的

分离这些东西的一种方法是打破依赖关系。在上述情况下,可能如下所示:

class A {
  B* b_;
public:
  A(B* b) : b_(b) {}
  void foo();   //1
};

class B {
public:
  void bar() { A a(this); a.foo(); }
  void meow() { /* ... */}
};

inline void A::foo() {b_->meow();} //2
class B_Interface
{
public: 
  virtual void meow() = 0;
};

class A {
  B_Interface* b_;
public:
  A(B_Interface* b) : b_(b) {}
  void foo() {b_->meow();} //OK this time
};

class B : public B_Interface {
public:
  void bar() { A a(this); a.foo(); }
  virtual void meow() { /* ... */}
};

这样做的代价是增加一个间接寻址,但分离了两个类的依赖关系,使测试等变得更容易。

我已经受够了,由于某种原因,它仍然无法工作,这是对我时间和精力的浪费。我又回到了一个构建良好的项目上,只使用了标题。

为什么要从一个构建良好的项目转移到一个只使用标题的项目?为了使用SDK,但现在我找到了一个替代解决方案,所以我回滚了!啊,对示例代码感到抱歉,我忘了说它们是在“public:”修饰符下定义的。我试图明确地公开这个类,也就是公开类。我将尝试一个SSCCE,尽快从任何建议中找到解决方案。
public类是Java还是C#