0

私は C++ が初めてで、マルチファイル プログラムを機能させるのに苦労しています。C で機能するグラフ ライブラリがあり、それを C++ に変換する際に問題が発生しています。g++ からの私の最大の問題は、このエラー メッセージです。

error: no match for âoperator=â in â*(((Graph*)this)->Graph::adj +
((long unsigned int)(((long unsigned int)i) * 32ul))) = (operator
new(32u), (<statement>, ((List*)<anonymous>)))â

これが私のGraph.cppコードのセクションです。

Graph::Graph(int n){
    order = n;
    size = 0;
    source = NIL;
    color = static_cast<char*>(calloc(n + 1, sizeof(char)));
    distance = static_cast<int*>(calloc(n + 1, sizeof(int)));
    parent = static_cast<int*>(calloc(n + 1, sizeof(int)));
    adj = static_cast<List*>(calloc(n + 1, sizeof(List*)));
    discover = static_cast<int*>(calloc(n + 1, sizeof(int)));
    finish = static_cast<int*>(calloc(n + 1, sizeof(int)));
    int i;
    for(i = 0; i <= n; i++){
        color[i] = 'w';
        distance[i] = INF;
        parent[i] = NIL;
        adj[i] = new List();
    }
}

ご覧のとおり、C と C++ のハイブリッドを少し使用していますが、純粋な C++ 実装も機能しません。私のファイルのさらに下に、私は常にエラーを受け取ります "エラー: â->â のベースオペランドには非ポインタ型 âListâ があります"。私はここを見回して、他の人がこのエラーについて不平を言っているのを見つけましたが、配列への割り当てに役立つのを見たことはありません. これを除いて、私はそれがすべて機能することを知っているので、助けは素晴らしいでしょう.

4

3 に答える 3

2

Graph::adj型であると宣言しましたList*(adj[i]を行うのと同じです*(adj+i))。型へのポインターを逆参照すると、T型の値が生成されますT。の種類はadj[i]ですList

しようとしていることを本当に実行したい場合は、 として宣言します。そうすればGraph::adjList**一連の へのポインターでListはなく、 への一連のポインターへのポインターになりますList


わからない、一体何を言おうとしているの?

タイプ の変数にList*( によって返される)を代入しようとしています。new ListList

struct List {
  // ... 
};

List ** adj = static_cast<List**> (
  std::calloc (10, sizeof (List*))
);

/* error

   List * adj = static_cast<List*> (
     std::calloc (10, sizeof (List*))
   );

*/

adj[0] = new List;

わかりました..しかし、この問題を解決するためのより良い方法があるに違いありませんか?

確かに、C++ が提供するものを使用して、古い C の習慣を捨ててください。

List * adj = new List [10]; // create an array of 10 List

adj[i].member_of_List ...;  // example

delete [] adj;              // free up allocated memory when you are done
于 2013-04-23T05:45:30.373 に答える
1

ライン

adj = static_cast<List*>(calloc(n + 1, sizeof(List*)));

adjがListオブジェクトの配列であることを示唆していますが、 line

adj[i] = new List();

ポインターの配列であることを示唆しています。adjの定義を確認する必要があります。ちなみにエラーは後段を指しています。

種類

C++ 型システムを中心に展開するこの問題の理論的側面について、もう少し詳しく説明します。

C++ では、すべての式に、コンパイル時に認識される型があります。フォームの任意の式の型

static_cast<List*>(...)

List *

つまり、括弧内の式の型を List * に静的にキャストできる場合、コンパイラは文句を言わず、式の最終的な型は List * になります。関数callocは、他のポインタにキャストできる void * を返します。実際、ポインターのキャストは、多くの場合、コンパイラーに「はい、私は自分が何をしているのか知っています、黙ってください」と伝える方法にすぎません。ほとんどのプラットフォームでは、すべてのポインター型が同じビット表現を持ちますが、標準ではそのようなことは義務付けられていないため、原則として、そのようなキャストを実装するためにマシン コードを生成する必要はありません。

のような式の型

new List()

また

new List[10]

List *

そのような命令を含む命令は、Listオブジェクトまたは 10 個のリスト オブジェクトに十分なスペースを割り当て、そのようなスペースへのポインタを返します。

回線を交換した方が良いかもしれません

adj = static_cast<List*>(calloc(n + 1, sizeof(List*)));

adj = new List[n + 1];

adjがポインター型の場合、次のような式の型

adj[i]

また

*(adj + i)

または単に

*adj

ポインター型からアスタリスクの 1 つを引いたものです。つまり、adjのタイプが

List *

adj[i]の型は

List

これが、 adj[i] = new List() ;行でエラーが発生する理由です。当てる意味がない

List *

List

幸いなことに、 adjnew演算子で割り当てると、すべての要素をnewで作成する必要がなくなる可能性があります。newで配列を割り当てると、そのすべての要素が作成され、それらのコンストラクターがコンパイラーによって自動的に呼び出されます。

考えられる解決策

プログラムの残りの部分は明らかに正しいので、単純に行を消去してください。

adj[i] = new List()

そして、すべてがうまくいくはずです。ただし、ジョンが指摘したように、あなたの意図はあまり明確ではありません。adjをオブジェクトの配列にしたい場合は、本当に教えてください

List *adj;

またはポインタの配列

List **adj;

高度なトピック

Cの方法を使用することの実際の違い

adj = static_cast<List*>(calloc(n + 1, sizeof(List*)));

またはC++の方法

adj = new List[n + 1];

割り当てられたListオブジェクトのそれぞれのコンストラクターが前者のメソッドで呼び出されないということですか。これが必要なポインターのアプリケーションがいくつかありますが、一般的には C と C++ を混在させるべきではありません。

于 2013-04-23T05:46:13.173 に答える
0

C と C++ のハイブリッド ミックスは、実際には純粋な C++ よりも難しくなります。

この場合、問題はあなたが持っているようです

class Graph
{
    ...
    List* adj;
    ...
};

それで

adj[i] = new List();

adj[i]はタイプで、タイプは であるListためnew List()、間違っていList*ます。

これを修正するには、placement newを使用します。

#include <new>

new (adj + i) List();

これは、あなたが達成しようとしているListアドレスを構築します。&adj[i]

ただし、これは高度な C++ であり、C と C++ を組み合わせて記述しようとしている場合にのみ必要です。Cパートはすぐに捨てます。

編集

refpが指摘しているように(そして私は見逃しました)、あなたは持っています

adj = static_cast<List*>(calloc(n + 1, sizeof(List*)));

私の答えは、それが間違いであり、あなたが意図した場合にのみ正しいです

adj = static_cast<List*>(calloc(n + 1, sizeof(List)));
于 2013-04-23T05:58:01.093 に答える