好吧,无论如何不是C/C++专家,但我认为头文件的目的是声明函数,然后C/CPP文件来定义实现.
但是,今晚回顾一些C++代码,我发现这是在类的头文件中...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
Run Code Online (Sandbox Code Playgroud)
那么为什么标题中有实现呢?是否与const关键字有关?这是内联类方法吗?与定义CPP文件中的实现相比,这样做的好处/意义究竟是什么?
有没有办法不必编写两次函数声明(头文件),并且在编译时仍然保持相同的可伸缩性,调试的清晰度和在C++中编程时的设计灵活性?
我是C++的新手,我有一些关于代码分离的一般问题.我目前在一个文件中构建了一个小应用程序.我现在想要做的是将它转换为单独的文件,使它们包含类似的代码或诸如此类的东西.我现在真正的问题是,我怎么知道如何分开事物?代码应该分开的隐形边际是什么?
另外,头文件有什么意义?它是否转发声明方法和类,以便在编译期间链接器包含它们之前我可以在我的代码中使用它们?
对方法或最佳实践的任何见解都会很棒,谢谢!
我必须处理一个由许多模板化类组成的库,这些类当然都是在头文件中实现的.现在我正试图找到一种方法来减少无法忍受的长编译时间,因为我几乎必须在每个编译单元中包含整个库.
尽管有模板,使用前向声明是否可能?我正在尝试下面的例子中的一些东西,我尝试绕过它#include <vector>,作为一个例子,但它给了我一个链接器错误,因为push_back未定义.
#include <iostream>
namespace std {
template<class T>
class vector {
public:
void push_back(const T& t);
};
}
int main(int argc, char** argv) {
std::vector<int>* vec = new std::vector<int>();
vec->push_back(3);
delete vec;
return EXIT_SUCCESS;
}
$ g++ fwddecl.cpp
ccuqbCmp.o(.text+0x140): In function `main':
: undefined reference to `std::vector<int>::push_back(int const&)'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我尝试了一次预编译的头文件但是根本没有改变编译时间(我确实确实加载了它们而不是真正的头文件).但是,如果你们都说预编译头应该是可行的方式,那么我将再试一次.
更新:有些人说,转发声明STL类是不值得的.我应该强调,vector上面的STL 只是一个例子.我并没有真正尝试向前声明STL类,但它是关于我必须使用的某些库的其他严格模板化的类.
更新2:有没有办法使上面的例子实际编译和链接正确?Logan建议使用-fno-implicit-templates并放在template class std::vector<int>某个地方,大概是一个.cpp可以编译的单独文件-fno-implicit-templates,但我仍然会遇到链接器错误.再次,我试图理解它是如何工作的,std::vector以便我可以将它应用于我实际使用的模板化类.
我的同事是0 2上的问题,他一直激励着(1,2),所以我想我应该给他一个机会,迎头赶上.
我们最近的分歧是关于将"const"放在声明上的样式问题.
他认为它应该在类型前面,或者在指针之后.原因在于,这是其他人通常所做的事情,其他风格可能会让人感到困惑.因此,指向常量int的指针和指向int的常量指针将分别为:
const int *i;
int * const i;
Run Code Online (Sandbox Code Playgroud)
但是,无论如何我很困惑.我需要的是一致的,易于理解的规则,我可以做的"常量"意义上的唯一方法是,它去后,它被修改的事情.有一个例外允许它在最终类型前面,但这是一个例外,所以如果我不使用它,它会更容易.
因此,指向常量int的指针和指向int的常量指针将分别为:
int const * i;
int * const i;
Run Code Online (Sandbox Code Playgroud)
作为一个额外的好处,以这种方式做事使得更深层次的间接更容易理解.例如,指向int的常量指针的指针显然是:
int * const * i;
Run Code Online (Sandbox Code Playgroud)
我的论点是,如果有人只是按照自己的方式学习,他们就可以轻松搞清楚上面的内容.
这里的最终问题是他认为将int放在int之后是如此难以言喻的丑陋,对可读性有害,以至于它应该在样式指南中被禁止.当然,我认为如果指南应该建议按照我的方式做,但无论哪种方式,我们都不应该禁止一种方法.
编辑: 我已经得到了很多好的答案,但没有一个真正直接解决我的最后一段("最终问题").很多人都争论一致性,但在这种情况下是如此理想,禁止其他方式这样做是一个好主意,而不是仅仅劝阻它?
我想知道在头文件中存储c ++常规函数,而不是方法(类中的方法)是否是一个好习惯.
例:
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
int add(int a, int b)
{
return a + b;
}
#endif
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
#include <iostream>
#include "Functions.h"
int main(int argc, char* args[])
{
std::cout << add(5, 8) << std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
这是好事吗?谢谢
某些类(如异常或模板)只需要头文件(.h),通常没有与之相关的.cpp.
我已经看到一些项目(对于某些类)没有与头文件关联的任何.cpp文件,可能是因为实现很短,直接在.h中完成,或者可能由于其他原因,例如模板类,必须在头文件中包含实现.
您的意见是什么,如果一个类太短,我应该避免创建.cpp文件并直接在头文件上编写代码?如果代码写在头文件中,我应该包含一个空的.cpp,以便项目中的文件保持一致吗?
作为一名新手C++程序员,我总是将我的类接口放在.h文件中并在.cpp文件中实现.但是我最近尝试了C#一段时间,我真的很喜欢它的清晰语法和组织文件的方式,特别是在标题和实现之间没有任何关系,你通常为每个.cs文件实现一个类,而你不需要标题.
我知道在C++中这也是可能的(你可以在.h文件中编写"内联"函数),但到目前为止,我总是看到C++项目中的文件.h和.cpp文件之间有明显的区别.这种方法有哪些优缺点?
谢谢
Boost.Asio 是一个很棒的库,但它有一个巨大的缺点——编译时间极慢。一个简单的HTTP协议实现(真的很简单)(大约1k行代码)在GCC 4.4下编译需要大约13.5s!
我尝试使用 PCH,但它并没有太多地改善编译时间(大约仅 1 秒)。
那么有没有关于如何使 Boost.Asio 编译时间更快的教程?
例如,我应该为哪个类准确包含哪些标头。
例如,我使用:io_service、tcp::ip::sockets、tcp::ip::acceptor、deadline_timer、 缓冲区和一些函数,如async_read、async_write。
有什么建议么?
PS:只要有可能,我都会使用 pimpl。
大多数C++类方法签名通常在头文件中的声明和我读过的代码中的源文件中的定义之间重复.我觉得这种重复是不可取的,而且这种代码编写方式会受到参考位置不佳的影响.例如,源文件中的方法通常引用头文件中声明的实例变量; 您最终必须在读取代码时不断在头文件和源文件之间切换.
有人会建议一种方法来避免这样做吗?或者,我是否主要通过不按常规方式做事来混淆经验丰富的C++程序员?
另请参阅问题538255头文件中的C++代码,其中有人被告知所有内容都应该放在标题中.
我刚刚创建了这个新类:
//------------------------------------------------------------------------------
#ifndef MULTITHREADEDVECTOR_H
#define MULTITHREADEDVECTOR_H
//------------------------------------------------------------------------------
#include <vector>
#include <GL/GLFW.h>
//------------------------------------------------------------------------------
template<class T>
class MultithreadedVector {
public:
MultithreadedVector();
void push_back(T data);
void erase(typename std::vector<T>::iterator it);
std::vector<T> get_container();
private:
std::vector<T> container_;
GLFWmutex th_mutex_;
};
//------------------------------------------------------------------------------
#endif // MULTITHREADEDVECTOR_H_INCLUDED
//------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
类的定义:
//------------------------------------------------------------------------------
#include "MultithreadedVector.h"
//------------------------------------------------------------------------------
using namespace std;
//------------------------------------------------------------------------------
template<class T>
MultithreadedVector<T>::MultithreadedVector() {
th_mutex_ = glfwCreateMutex();
}
template<class T>
void MultithreadedVector<T>::push_back(T data) {
glfwLockMutex(th_mutex_);
container_.push_back(data);
glfwUnlockMutex(th_mutex_);
}
template<class T>
void MultithreadedVector<T>::erase(typename vector<T>::iterator it) {
glfwLockMutex(th_mutex_);
container_.erase(it);
glfwUnlockMutex(th_mutex_);
}
template<class T>
vector<T> …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的类,我想将它合并到一个.h文件中.如果我将.cpp的内容剪切并粘贴到我的.h的底部,一切都会一样吗?
特别是,int MyClass::myStaticVar = 0;在.cpp顶部的任何类定义之外都有静态成员变量初始化 ,然后是静态成员函数实现void MyClass::myStaticMethod() {...}.一些非静态成员函数已经在.h中实现,而不是.cpp.所以你可以看到这里有一些细微差别我想澄清一下.
编辑到目前为止,我得到的是:
这很顽皮,但是如果你只有
#include.h一次它会起作用.它破坏了惯例,并没有像.h那样真正起作用,所以它也可能被命名为.doofus.
现在,例如,查看TUIO C++绑定.很多类都包含一个.h文件,没有cpp(TuioPoint.h,TuioCursor.h,TuioObject.h等).我不认为这太糟糕了......
我开始使用C++,我来自C和Java.我知道在C中强烈建议在源代码的头和变量/类型/函数定义中编写变量/类型/函数声明; 所以,当我开始使用C++进行编码时,我认为也遵循相同的约定.
对我来说不幸的是,在C++中,此规则有几个例外,其中包括:
这让我对文件产生了一些困惑:它们中的大多数是*.cpp包含少量中/大成员函数的文件的标题.
所以我的问题是:假设只使用类进行编码,而不是使用普通的C,为什么我不能只将所有内容放在标题中并且没有cpp文件?(有点Java风格); 澄清:我将主要处理类,模板类,最多模板函数.
例如Foo.hpp:
class Foo {
public:
foo() {
//body
}
bar() {
//body
}
}
Run Code Online (Sandbox Code Playgroud)
而不是在*.hpp和之间划分*.cpp:
//file Foo.hpp
class Foo {
public:
foo();
bar();
}
//file Foo.cpp
Foo::foo() {
//body
}
Foo::bar() {
//body
}
Run Code Online (Sandbox Code Playgroud)
当然会放入类似静态全局变量的东西.*cpp,但是根据我的理解,它们是唯一需要放入cpps的东西(并且强烈建议不要使用它们).
你能否告诉我这种方法有哪些缺点?作为C++的初学者,我肯定会忽略一些重要的因素.在我天真的观点中,没有什么需要在cpp文件中(假设我只编写类当然).
谢谢
c++ ×13
header ×3
header-files ×3
coding-style ×2
compilation ×2
boost-asio ×1
codeblocks ×1
conventions ×1
dry ×1
function ×1
linker ×1
templates ×1