C ++编程风格

我是一个老的(但不太老)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;
};

该类位于头文件和构造函数中:

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
    _class.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // Optional
    _class.lpszMenuName = 0;
    _class.lpszClassName = className;   // Mandatory
}

位于.cpp源文件。

我可以做的是:

class WinClass
{
    public:
        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
            _class.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // Optional
            _class.lpszMenuName = 0;
            _class.lpszClassName = className;   // Mandatory
        }

        void Register ()
        {
            ::RegisterClass (&_class);
        }

    private:
        WNDCLASS _class;
};

现在构造函数在它的类中。


除了其他人在这里所说的话之外,还有更重要的问题:

1)大型翻译单元导致更长的编译时间和更大的目标文件大小。

2)循环依赖! 这是最大的一个。 它几乎总是可以通过拆分标题和源代码来解决:

// Vehicle.h
class Wheel {
    private:
        Car& m_parent;
    public:
        Wheel( Car& p ) : m_parent( p ) {
            std::cout << "Car has " << m_parent.numWheels() << " wheels." << std::endl;
        }
};

class Car {
    private:
        std::vector< Wheel > m_wheels;
    public:
        Car() {
            for( int i=0; i<4; ++i )
                m_wheels.push_back( Wheel( *this ) );
        }

        int numWheels() {
            return m_wheels.size();
        }
}

不管你把这些命令放在什么位置,人们总是会缺乏另一个的定义,即使使用前向声明也不行,因为函数体中正在使用关于每个类的符号的细节。

但是,如果将它们分解为适当的.h和.cpp文件并使用前向声明,它将满足编译器的要求:

//Wheel.h
//-------
class Car;

class Wheel {
private:
    Car& m_parent;
public:
    Wheel( Car& p );
};

//Wheel.cpp
//---------
#include "Wheel.h"
#include "Car.h"

Wheel::Wheel( Car& p ) : m_parent( p ) {
        std::cout << "Car has " << m_parent.numWheels() << " wheels." << std::endl;
}

//Car.h
//-----
class Wheel;

class Car {
private:
    std::vector< Wheel > m_wheels;
public:
    Car();
    int numWheels();
}

//Car.cpp
//-------
#include "Car.h"
#include "Wheel.h"

Car::Car() {
        for( int i=0; i<4; ++i )
            m_wheels.push_back( Wheel( *this ) );
}

int Car::numWheels() {
        return m_wheels.size();
}

现在,实际上必须知道关于第二类的细节的代码可以包含头文件,该文件不需要知道关于第一类的细节。

当源文件提供定义时,标题只提供声明。 或者说另一种说法:标题告诉你什么是(有效的符号可用)和源代码告诉编译器这些符号实际上做了什么。 在C ++中,除了有效的符号外,不需要任何东西就可以开始使用它。

相信C ++有这个习惯用法的一个原因,因为如果你不这样做,你会为自己的生产线造成很多麻烦。 我知道 :/


在构建代码时,C ++预处理器会构建一个翻译单元。 它以.cpp文件开头,解析#includes从头文件中获取文本,并生成一个包含所有头文件和.cpp代码的大文本文件。 然后,这个翻译单元被编译成将在您定位的平台上运行的代码。 每个翻译单元最终成为一个目标文件。

因此,.h文件包含在多个翻译单元中,并且.cpp文件仅包含在一个中。

如果.h文件包含很多东西(包括实现),那么翻译单元会相应地变大。 编译时间会增加,并且当您更改标题中的任何内容时......每个使用它的翻译单元都需要重新编译。

所以..最小化.h文件中的东西大大提高了编译时间。 您可以编辑.cpp文件来更改函数,并且只需要重建一个翻译单元。

为了完成关于编译的故事......
一旦所有的翻译单元都被构建成目标文件(本地平台的本地二进制代码)。 链接器完成它的工作,并将它们拼接到你的.exe,.dll或.lib文件中。 .lib文件可以链接到另一个版本,因此可以在多个.exe或.dll中重复使用.lib文件。

我认为Java编译模型更加先进,并且放置代码的位置意义不大。


.h和.cpp文件通常将声明和定义分开,这里有一些顺序和概念封装。 头文件有'什么',实现文件有'如何'。

我发现在java中的一个文件中的一切都是混乱的。 所以,每一个都是属于自己的。

就像任何其他语言对其社区习惯用法一样,C ++惯例和惯用语都经过深思熟虑的推理。

我认为最好是在你编写Java时使用java(作为动词),当使用C ++时使用C ++! 你会明白为什么有语言的经验。 与切换到任何新语言相同。

链接地址: http://www.djcxy.com/p/85407.html

上一篇: C++ programming style

下一篇: Visual studio 2012 slow compile time