2

私は、c ++アプリケーションで、次のようなヘッダーとソースファイルを含む名前空間宣言のみを使用していることを時々見ました。

#ifndef _UT_
#define _UT_

#include <string>
#include <windows.h>

namespace UT 
{
    void setRootPath(char* program_path, char* file_path);
    char * ConvertStringToCharP(std::string str);
};

#endif

//and then in UT.cpp
#include "UT.h"

namespace UT 
{
    char * ConvertStringToCharP(std::string str)
    {
        char * writable = new char[str.size() + 1];
        std::copy(str.begin(), str.end(), writable);
        writable[str.size()] = '\0';  
        return writable;
    }

    void setRootPath(char* program_path, char* file_path) 
    {
        //...
    }
}

静的メソッドを使用してクラシッククラスを定義するよりも優れていますか?
または単に単純なクラス?
このメソッドは、コンパイラリンカーにとってより良いものを持っていますか?

この名前空間のメソッドは、何度も呼び出されます。

4

6 に答える 6

5

staticパフォーマンスに関しては、クラスメンバーとフリー関数の間に違いはありませんnamespace。しかし、それは論理の問題です。あなたの関数はクラスに関連していますか?

自問するのに良い質問です-組織を改善するためだけに(またはグループ化するために)クラス内にメンバー関数を作成していますか?static答えが「はい」の場合は、おそらくを使用する必要がありますnamespace

于 2012-06-11T13:51:28.453 に答える
5

偶然の一致で、StackOverflowのわずかに異なる質問についてこの回答を読んだことがあります。その点で、ユーザーrhalbersmaは、著者のScott Meyersがクラスの外部(非フレンドメソッド)で実装されたメソッドが実際にカプセル化を改善する方法を説明しているDrDobbの記事への素晴らしいリンクを提供しました。私にとって、それは今日にとって良い学習でした。これがあなたにも役立つことを願っています。

于 2012-06-11T14:02:44.693 に答える
4

メソッドの意味がクラスから独立している場合は、すべてのクラスの外にメソッドを配置します。他の言語(Java、C#)の静的クラスは、メソッドをクラスの外に置くことができないことを補う方法です。C ++は名前空間を介してこの機能をすぐに提供するため、追加の「静的クラス」を使用すると、コードの読者にとって直感に反します。

于 2012-06-11T13:54:08.607 に答える
1

静的メンバー関数を使用する主な理由classは、クラスとそのメンバーとの論理的および概念的な関係です。

もう1つの理由は、テンプレートの部分的な特殊化を有効にすることです。これは、関数テンプレートでは許可されていませんが、クラスでは許可されています。

それ以外の場合は、スタンドアロン関数(適切なで定義されているnamespace)を使用します。

于 2012-06-11T13:58:13.850 に答える
0

デフォルトでは、常にクラスのメソッドを最小化するようにしてください。クラス内ではなくクラスの観点から機能を実装できる場合は、そうする必要があります。言い換えれば、すでに公開されているパブリックインターフェイスを使用して目的の機能を実現できる場合は、そうする必要があります。これにより、コードの実装の詳細への依存が大幅に減少します。

したがって、クラスの外部で、クラスに自然に関連しているように見える適切な名前空間に実装できる場合。

編集:OPは、ユーティリティ/関連関数のホルダーオブジェクトとして名前空間または静的クラスのどちらを実装するかについて実際に質問しているようです。私の意見では、名前空間はこれを行うための正しい方法です。クラスは必要ありません。

于 2012-06-11T14:03:05.613 に答える
0

絶対的なルールはありませんが、一般に、関数が非常に高い一貫性を示し、何らかの理由で「名前空間」を閉じてクライアントが関数を追加できない場合を除いて、を使用するnamespace 方が一般的に使用することをお勧めしますclass。もちろん、それらをテンプレートで使用できるようにすることが目的でない限り、テンプレートをクラスでインスタンス化することはできますが、名前空間でインスタンス化することはできません。(この手法は「トレイト」と呼ばれることがよくあります。非静的メンバーを持たないクラスは、トレイトクラスと呼ばれます。)

名前空間を使用する場合でも、関数を定義する必要があります。

void UT::setRootPath( char const* programPath, char const* filePath)
{
    //  ...
}

char* UT::convertStringToCharP( std::string const& str )
{
    //  ...
}

このようにして、関数のシグニチャのタイプミスがコンパイラによって検出されます。

于 2012-06-11T14:31:28.740 に答える