我是一个老的(但不是太老)Java程序员,决定学习C++.但我已经看到了很多C++编程风格,是......好吧,该死的!
把类定义放在头文件中的所有东西,以及不同源文件中的方法 - 调用函数无处不在,而不是使用类中的方法.所有这一切似乎......错了!
最后,有没有理由让我继续对OOP进行大屠杀,以及编程中任何好的和正义的东西,或者我可以忽略那些老式的C++约定,并使用我良好的Java编程风格?
顺便说一句,我正在学习C++,因为我想做游戏编程.
这是一个例子:
在C++网站上,我找到了一个Windows实现:
class WinClass
{
public:
WinClass (WNDPROC wndProc, char const * className, HINSTANCE hInst);
void Register ()
{
::RegisterClass (&_class);
}
private:
WNDCLASS _class;
};
Run Code Online (Sandbox Code Playgroud)
该类位于头文件和构造函数中:
WinClass::WinClass (WNDPROC wndProc, char const * className, HINSTANCE hInst)
{
_class.style = 0;
_class.lpfnWndProc = wndProc; // Window Procedure: mandatory
_class.cbClsExtra = 0;
_class.cbWndExtra = 0;
_class.hInstance = hInst; // Owner of the class: mandatory
_class.hIcon = 0;
_class.hCursor = ::LoadCursor (0, IDC_ARROW); // Optional …Run Code Online (Sandbox Code Playgroud) 并不是说谷歌风格指南是神圣的圣经,但作为一个新手程序员,它似乎是一个很好的参考.
Google样式指南列出了前向声明的以下缺点
前向声明可以隐藏依赖项,允许用户代码在标题更改时跳过必要的重新编译.
随后对库的更改可能会破坏前向声明.函数和模板的前向声明可以防止标题所有者对其API进行其他兼容的更改,例如扩展参数类型,添加具有默认值的模板参数或迁移到新的命名空间.
从名称空间std ::转发声明符号会产生未定义的行为.
可能很难确定是否需要前向声明或完整#include.用前向声明替换#include可以默默地改变代码的含义:
码:
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
Run Code Online (Sandbox Code Playgroud)
如果#include被B和D的forward decls替换,test()将调用f(void*).
从标题中声明多个符号的前向可能比简单地#include the header更加冗长.
构造代码以启用前向声明(例如,使用指针成员而不是对象成员)可以使代码更慢,更复杂.
然而,对SO的一些搜索似乎表明,前向声明通常是更好的解决方案.
因此,鉴于这些看似非平凡的缺点,有人可以解释这种差异吗?
什么时候忽略部分或全部这些缺点是安全的?
为了减少工作中相当大的框架的编译时间,我考虑将.h文件中的类方法定义移动到它们关联的.cpp文件中,如果它们非常大或者需要包括编译可以移动到关联的文件. cpp文件.为清楚起见,下面是一个人为的例子(虽然Foo::inc是一个很小的方法)
main.cpp:
#include "Foo.h"
int main(int argc, char** argv) {
Foo foo(argc);
foo.inc();
return foo.m_argc;
}
Run Code Online (Sandbox Code Playgroud)
之前是Foo.h(还不需要Foo.cpp):
class Foo {
public:
int m_argc;
Foo (int argc) : m_argc(argc) {}
void inc() { m_argc++; }
};
Run Code Online (Sandbox Code Playgroud)
Foo.h之后:
class Foo {
public:
int m_argc;
Foo (int argc) : m_argc(argc) {}
void inc();
};
Run Code Online (Sandbox Code Playgroud)
Foo.cpp:
#include "Foo.h"
void Foo::inc() { m_argc++; }
Run Code Online (Sandbox Code Playgroud)
很久以前,一位同事提到可能存在导致运行时性能下降的情况.我在谷歌上寻找这个案子,但似乎无法找到它,这个问题的接受答案是我能找到的最接近的答案,但它没有给出案例,只是提到它可能发生:从标题中移动内联方法文件到.cpp文件
在旁注中,我对方法明确使用的情况不感兴趣,inline我上面链接的答案就是我能找到的最接近我正在寻找的方法
什么情况(如果有的话)可能导致运行时间减慢?
对于主要包含C++项目的解决方案,在Visual Studio 2005中加快编译时间的最佳方法是什么?
我std::chrono用来跟踪从实例化到每次调用的时间someMethod().
最小的示例代码如下所示:
#include <chrono>
class TestClass
{
public:
TestClass();
void someMethod();
private:
std::chrono::time_point<std::chrono::steady_clock> m_timeBegin;
};
Run Code Online (Sandbox Code Playgroud)
TestClass::TestClass() :
m_timeBegin(std::chrono::steady_clock::now())
{
}
void TestClass::someMethod()
{
auto timeNow = std::chrono::steady_clock::now();
auto msSinceCreation =
std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_timeBegin);
}
Run Code Online (Sandbox Code Playgroud)
我想摆脱#include头部.
除了编译和链接时间,我主要关心的是封装.使用std:chrono仅与实施相关.为了使用Testclass它绝对没有必要使用它甚至不知道它涉及到.
这是一些可能的情况.如果有人使用TestClass决定使用std::chrono,他可以做到而无需添加#include.然后,如果将来执行TestClass更改停止使用std:chrono(并因此删除#include),其他代码将无理由地停止编译.
显然,那个忘记添加包含的人做错了.但显然我们会喜欢或不喜欢这种情况.
因为它可能与某些解决方案相关,SomeMethod()所以经常调用,性能在我的场景中很重要.