-1
#include "average.c++"
#include "name.c++"

class Grade {
public:
  Grade() {}
  void searcharray(Name *array[]) {
    int i;
    for(i = 0; i <= 10; i++){
      printf("%s", array->name);
    }
  }
};

int main() {
  int i;
  char line[64];
  Name *names[10];
  for(i = 0; i < 5; i++){
    scanf("%s", &line);
    names[i] = new Name(line);
  }
  Grade *test;
  test = new Grade();
  test->searcharray(names);
}

このコードは、エラー "grade.c++ in member function 'void Grad::searcharray(Name* )': grade.c++:11:25: error: request for member 'name' in ' array' を返します。これはポインター型です。 'Name*' ('->' を使用するつもりだったのでしょうか?)" これを機能させるには助けが必要です。Javaのようにクラスを拡張するような単純なものだと思いますが、これがc ++でどのように機能するかはわかりません。C で配列だけを使用する場合と同じように、オブジェクトの配列をクラスに渡すことができると想定しています。私の質問の根本は、解決策を見つけて、このコードが間違っている理由を見つけることです。

4

2 に答える 2

2

標準ライブラリを利用することで、コードを大幅に改善できます。最初のコードの問題は、C スタイルの配列 (技術的には、それが崩壊したポインター) がarray->nameどこにあったかということでした。array最初にインデックスでポインターを取得しない限り、そのような式は不可能です。

array[i]->name;

また、その行が書かれている for ループは、配列 1 を何度もトラバースしています。条件ステートメントは、配列の末尾を超えてアドレスを逆参照しないようにするi <= 10必要があります。i < 10

とにかく、コードを修正して表示する代わりに、ベクトル、メモリ管理、およびstd::string. これが役立つことを願っています:

#include <iostream>
#include <string>
#include <vector>
#include <memory>

class Grade
{
public:
    Grade() { }

    static void searcharray(const std::vector<std::unique_ptr<Name>>& array)
    {
        for (const auto& obj : array)
        {
            std::cout << obj->name;
        }
    }
};

int main()
{
    std::string name;
    std::vector<std::unique_ptr<Name>> names;

    while (std::cin >> name)
        names.push_back(std::unique_ptr<Name>(new Name(name)));
    //  names.push_back(std::make_unique<Name>(name))

    Grade::searcharray(names);
}

searcharray staticの特定のインスタンスとは関係がないため、私も作成したことに注意してくださいGrade

于 2013-10-28T19:54:44.093 に答える
1

他の人が指摘しているように、問題は次のName *array[]ように宣言されたパラメーターを使用していることですarray->name

Cの上に構築されたC++は、「宣言は使用を模倣する」という規則に従います。つまり、変数が宣言される方法は、使用される方法のように見えます。したがって、次の宣言を使用します。

Name *array[]

これから名前を取得する方法は次のとおりです。

*array[i]

Andnameは のメンバーであるため、最初にオブジェクトNameを取得する必要があります。Name次に、メンバー アクセスを追加できます。

(*array[i]).name

そして、 -> ショートカットを使用できます。ここ(*x).yで、 は と同じx.yです:

array[i]->name

その他の問題:

あなたのコードは、1989 年または 1990 年バージョンの C に必要なコード スタイルに大きく影響されているようです。C++ コードの記述が必要以上に悪くなるため、それを避けるようにしてください。

a を宣言して、Grade *すぐに割り当てます。宣言と初期化を次のように組み合わせることができます。

Grade *test = new Grade();

ただし、とにかくポインタを使用する必要はありません: を使用しますGrade test;(ポインタが必要な場合は、スマート ポインタを使用する必要があります。決して 'naked' を使用しないでくださいnew。)

同様にnew、名前を作成するときにも回避できます。

Name names[10]; // assuming that Name is default constructible
for(...) {
  ...
  name[i] = Name(line);
}

ここでは、固定サイズの配列を避ける必要があります。代わりに、デフォルトで以下を使用する必要がありますstd::vector

std::vector<Name> names;
for (...) {
  ...
  names.push_back(Name(line)); // or in C++11 names.emplace_back(line);
}

i変数は、for ループの外側の変数としてではなく、for ループの一部として宣言する必要があります。

for (int i=0; i<10; ++i)

scanf入力を読み取るときは、固定サイズのバッファーを避ける必要があります。代わりに、行を読んでいる場合は、おそらく and から始める必要がstd::getlineありstd::stringます。

std::string line;
while (std::getline(std::cin, line)) { // read as many lines as there are, not just 10 no matter what
  names.emplace_back(line);
}
于 2013-10-28T20:40:01.457 に答える