2

可能な限り、コンパイルを高速化するために、includeではなく前方宣言を使用することを理解しています。

私はこのようなクラスを持っていPersonます。

#pragma once

#include <string>

class Person
{
public:
    Person(std::string name, int age);
    std::string GetName(void) const;
    int GetAge(void) const;
private:
    std::string _name;
    int _age;
};

Studentそしてこのようなクラス

#pragma once

#include <string>

class Person;

class Student
{
public:
    Student(std::string name, int age, int level = 0);
    Student(const Person& person);
    std::string GetName(void) const;
    int GetAge(void) const;
    int GetLevel(void) const;
private:
    std::string _name;
    int _age;
    int _level;
};

Student.hには、変換コンストラクターでclass Person;使用する前方宣言があります。Person罰金。しかし、私はコードで#include <string>使用している間のコンパイルエラーを避けるために行いました。std::stringここで前方宣言を使用してコンパイルエラーを回避するにはどうすればよいですか?出来ますか?

ありがとう。

4

5 に答える 5

4

stringとして使用されて以来

std::string _name;
//^^^^^^^^^ concrete member    

の構造全体stringが必要になるため、宣言が必要です。あなたはしなければなりません#include <string>


の宣言は、次のstringように書くと省略できます。

std::string* _name;
//^^^^^^^^^^ pointer or reference

これは前方宣言を使用できますが、PersonやStudentのような単純な構造型ではなく、多くのテンプレートを含む非常に複雑な型であるため、使用しないことをお勧めします。std::string

template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string { ... };
typedef basic_string<char> string;

誤って前方宣言した場合(たとえばclass string;)、型が競合しているため、実際に使用したときにコンパイルが失敗します。

于 2010-06-07T11:55:14.093 に答える
2

前方宣言は、ポインターと参照でのみ使用できます(これらは、参照するオブジェクトのサイズに関係なく、固定サイズであるため)。値で特定のクラスを使用する場合、コンパイラーは(正確なサイズを知るために)完全な定義を必要とするため、前方宣言では不十分です。

したがって、このように定義するStudent

class Student
{
public:
    ...
    Student(const Person person);
    ...
private:
    Person person;
};

上記のクラスメンバーのいずれかが、#includeヘッダーのPerson.hを強制します。

前方宣言はコンパイルの依存関係を回避するのに役立ち、コンパイル時間を短縮することをよく理解しています。ただし、これは主にユーザー定義のヘッダーに関係します。これらは頻繁に変更される可能性があるためです。標準ライブラリヘッダーは変更されないため、このような場合の節約は重要ではありません。

于 2010-06-07T11:52:56.143 に答える
1

関数/メソッドポインタパラメータのプロトタイプで宣言された型を使用する場合など、型の識別には前方宣言のみを使用できます。メンバー変数(つまり、std :: string _name;)を宣言する場合、コンパイラーは前方宣言で提供できるよりも少し多くを必要とします。たとえば、誰かがsizeof(Student)を実行した場合、コンパイラはサイズを把握するために宣言全体にアクセスできる必要があります。

于 2010-06-07T11:52:30.963 に答える
0

たぶん、継承を使用することも検討してください。

#include "Person.h" // i am afraid you need to

class Student : public Person
{
     ...

     protected:
         int _level;
         // no name and age, that is inhertianced from person
         // (if you want to access them from student, you maybe need to make them protected)
 };
于 2010-06-07T11:58:36.680 に答える
0

前方宣言は、包含を減らし、循環依存を解決するために使用されます。ただし、クラスのパブリックインターフェイスまたは保護されたインターフェイスで転送を使用する場合は、クラスのユーザーに正しいヘッダーファイルをインクルードする負担がかかります。これに加えて、STLで定義された転送タイプが期待どおりに機能しない場合があります。たとえば、std::stringは。として定義される場合がありますtypedef basic_string<char> string;。で前方に宣言するとnamespace std{ class string;}、コンパイルエラーが発生します。

于 2010-06-07T12:10:36.967 に答える