32

I have two files:

File1.cpp
File2.cpp

File1 is my main class which has the main method, File2.cpp has a class call ClassTwo and I want to create an object of ClassTwo in my File1.cpp

I compile them together by

g++ -o myfile File1.cpp File2.cpp

but when I try to create by

//create class two object

ClassTwo ctwo;

It doesn't work.

Error was

ClassTwo was not declared in this scope.

This is my main.cpp

#include <iostream>
#include <string>
using namespace std;

int main()
{
//here compile error - undeclare ClassTwo in scope.
ClassTwo ctwo;

//some codes
}

Here is my File2.cpp

#include <iostream>
#include <string>

using namespace std;

class ClassTwo
{
private:
string myType;
public:
void setType(string);
string getType();
};


void ClassTwo::setType(string sType)
{
myType = sType;
}

void ClassTwo::getType(float fVal)
{
return myType;
}

Got respond of splitting my File2.cpp into another .h file but if i am declaring a class, how do i split it into another .h file as i need to maintain the public and private of the variable(private) and functions(public) and how do i get ClassTwo ctwo to my File1.cpp at main method

4

5 に答える 5

71

コードの基本的な問題は何ですか?

コードは、インターフェイス (.h) と実装 (.cpp) に分離する必要があります。
次のようなものを書くとき、コンパイラは型の構成を確認する必要があります

ClassTwo obj;

これは、コンパイラがClassTwoの定義を確認する必要があるため、型のオブジェクトに十分なメモリを予約する必要があるためですClassTwo。C++ でこれを行う最も一般的な方法は、コードをヘッダー ファイルとソース ファイルに分割することです。
クラスの定義はヘッダー ファイルに入りますが、クラスの実装はソース ファイルに入ります。このようにして、作成したオブジェクトのクラスの定義を確認する必要がある他のソース ファイルにヘッダー ファイルを簡単に含めることができます。

すべてのコードを単純に cpp ファイルに入れて、それらを他のファイルに含めることができないのはなぜですか?

すべてのコードをソース ファイルに単純に配置して、そのソース ファイルを他のファイルに含めることはできません。C++ 標準では、エンティティを必要な回数だけ宣言できますが、定義できるのは 1 回だけです ( 1 つの定義規則 (ODR) ) 。 . ソース ファイルを含めると、ファイルが含まれるすべての翻訳単位でエンティティのコピーが作成されるため、ODR に違反します。

この特定の問題を解決するにはどうすればよいですか?

コードは次のように構成する必要があります。

// File1.h

Define ClassOne 

// File2.h

#include <iostream>
#include <string>


class ClassTwo
{
private:
   string myType;
public:
   void setType(string);
   std::string getType();
}; 

//File1.cpp

#include"File1.h"

Implementation of ClassOne 

//File2.cpp

#include"File2.h"

void ClassTwo::setType(std::string sType)
{
    myType = sType;
}

void ClassTwo::getType(float fVal)
{
    return myType;
} 

//main.cpp

#include <iostream>
#include <string>
#include "file1.h"
#include "file2.h"
using namespace std;

int main()
{

    ClassOne cone;
    ClassTwo ctwo;

    //some codes
}

ヘッダーファイルを含める代わりの手段はありますか?

コードで実際のオブジェクトではなくポインターのみを作成する必要がある場合は、前方宣言を使用することもできますが、前方宣言を使用すると、コンパイラがその型を不完全な型と見なすため、その型の使用方法にいくつかの制限が追加されることに注意してください。

于 2012-10-04T18:56:50.140 に答える
18

C++ (および C) は、型、関数、およびクラスの「宣言」と「実装」を分割します。ヘッダー ファイル (.h または .hpp) で必要なクラスを「宣言」し、対応する実装を .cpp ファイルに配置する必要があります。次に、どこかでクラスを使用 (アクセス) したい場合は、対応するヘッダーファイルを #include します。

ClassOne.hpp:

class ClassOne
{
public:
  ClassOne(); // note, no function body        
  int method(); // no body here either
private:
  int member;
};

ClassOne.cpp:

#include "ClassOne.hpp"

// implementation of constructor
ClassOne::ClassOne()
 :member(0)
{}

// implementation of "method"
int ClassOne::method()
{
  return member++;
}

main.cpp:

#include "ClassOne.hpp" // Bring the ClassOne declaration into "view" of the compiler

int main(int argc, char* argv[])
{
  ClassOne c1;
  c1.method();

  return 0;
}
于 2012-10-04T19:01:07.870 に答える
2

ヘッダーが必要ない場合は、クラスの名前を前方宣言する必要があります。

class ClassTwo;

重要:これは一部のケースでのみ機能します。詳細については、Als の回答を参照してください。

于 2012-10-04T19:01:40.103 に答える
2

2 つの.cppファイルを同時にコンパイルしても、お互いを「認識」しているわけではありません。File1.cppを「伝える」ファイルを作成する必要があります。実際にはClassTwoのような関数とクラスがあります。このファイルはヘッダーファイルと呼ばれ、多くの場合、実行可能コードは含まれていません。(インライン関数などには例外がありますが、最初は忘れてください) どの関数が利用可能かを伝えるためだけに、宣言的な必要性を提供します。

を取得File2.cppして に含めるとFile1.cpp、小さな問題が発生します。同じコードが 2 回ありFile1.cppますFile2.cpp

File1.hppしたがって、またはのようなヘッダー ファイルを作成する必要がありますFile1.h(他の名前も可能ですが、これは単に標準です)。次のように機能します。

//File1.cpp

void SomeFunc(char c) //Definition aka Implementation
{
//do some stuff
}

//File1.hpp

void SomeFunc(char c); //Declaration aka Prototype

そして、コードをきれいにするために、次を の先頭に追加できますFile1.cpp

#include "File1.hpp"

そして、次File1.hppの のコードを囲みます。

#ifndef FILE1.HPP_INCLUDED
#define FILE1.HPP_INCLUDED
//
//All your declarative code
//
#endif

これにより、コードの重複に関して、ヘッダーファイルがよりクリーンになります。

于 2012-10-04T19:23:18.140 に答える
1

コードをresult(実行可能ファイル、ライブラリなど)に変換する場合、2つのステップがあります:
1)コンパイル
2)リンク
最初のステップでは、コンパイラは、使用するオブジェクトのsizeof、関数のプロトタイプ、そして多分継承。一方、リンカは、コード内の関数とグローバル変数の実装を見つけたいと考えています。

ClassTwoこれで、コンパイラで使用するとき、File1.cppそれについて何も知らず、それに割り当てるメモリの量や、たとえば、それが持っているwitchメンバー、またはクラスと列挙型、またはintのtypedefでさえもわからないため、コンパイルは失敗します。コンパイラ。追加File2.cppすると、実装を探すリンカーの問題が解決されますが、コンパイラーはタイプについて何も知らないため、まだ不満を持っています。

したがって、コンパイルフェーズでは常に1つのファイル(およびもちろんその1つのファイルに含まれるファイル)で作業し、リンクフェーズでは実装を含む複数のファイルが必要になることを忘れないでください。また、C / C ++は静的に型指定されており、識別子がさまざまな目的(definition、typedef、enum classなど)で機能するため、常にコンパイラーに対して識別子を識別してから使用する必要があります。ルールとして、コンパイラーは変数のサイズを常に知っておいてください!!

于 2012-10-04T20:36:53.440 に答える