18

私は初めてでc++、コンストラクターとクラスに問題があります。だから、これが私のヘッダーファイルです:

#pragma once
#include <string>
using namespace std;
class test
{

    private:
    string name;
    int number;

public:

    test();
    test(string i,int b);
};

これはcppファイルです:

#include "test.h"
#include <string>
using namespace std;


test::test(){}

test::test(string i,int b){
    this->name=i;
    this->number=b;
}

今、私が電話しようとすると

test t=new test("rrr",8);

私は得る:

1   IntelliSense: no suitable constructor exists to convert from "test *" to "test" 

では、*名前にクラスが含まれているとどうなりますか(たとえば、.cppファイルのないクラスにはアステリックスがありませんが、他のすべてのクラスにはアステリックスがあります)。そして、私は何を間違えますか?

4

6 に答える 6

47

あなたはJava/C#のバックグラウンドから来ていると思います。 tここでは参照型ではなく、値型です。 newオブジェクトへのポインタを返します。したがって、次のいずれかが必要です。

test t = test("rrr", 8);
test t("rrr", 8);
test *t = new test("rrr", 8);

ポインタにまだ慣れていない場合は、最後のポインタを絶対に使用しないでください。しかし、ポインタのセマンティクスを理解することはかなり重要です。教科書の関連する章を読むことをお勧めします...

于 2013-03-26T12:54:54.410 に答える
7

したがって、名前に「*」が含まれているクラスの場合はどうなりますか(たとえば、.cppファイルのないクラスにはアステリックスがありません。他のすべてのクラスにはアステリックスがあります)???

あなたは間違いなくポインタについて学ぶ必要があります。test *C++では2つの完全にtest異なるタイプです。これらのタイプの2つの変数は次のとおりです。

test t;
test* p;

ここでtは、タイプtest、およびpタイプとしてがありtest*ます。test*「ポインタ」と表現しますtest

多くの場合、ポインタはオブジェクトのメモリアドレスであると考えることができます。したがって、pでは、ポインタであるため、のメモリアドレスを格納できます。tこれはtest。です。オブジェクトのアドレスを取得するには、次の&ように単項演算子を使用します。

test t;
test* p = &t;

t それはtestオブジェクトであることに注意してください。あなたは言う必要はありませんでしたnew test()。ここで、C ++は、C#やJavaなど、使用した可能性のある他の言語とは異なります。上記のC++コードでtは、はtestオブジェクトです。

ただし、を使用してオブジェクトを作成できるnew test()ので、違いは何ですか?

test t;test自動保存期間でオブジェクトを作成します。これは、スコープの最後で破棄されることを意味します(多くの場合、関数はその中で宣言されています)。

new test()test動的な保存期間を持つオブジェクトを作成します。これは、オブジェクトを手動で破棄する必要があることを意味します。そうしないと、メモリリークが発生します。この式はポインタを返すため、ポインタオブジェクトを初期化できます。

test* p = new test();

それでは、問題を見てみましょう。

test t=new test("rrr",8);

これで、が(a )new test("rrr", 8)へのポインタを返すことがわかりました。ただし、それをオブジェクトに割り当てようとしています。あなたは単にこれを行うことはできません。1つはアドレスで、もう1つはです。したがって、コンパイラは「からに変換するのに適したコンストラクタは存在しません」と言います。今は理にかなっていますね。testtest*testtesttest *test

代わりに、自動保存期間を使用することをお勧めします。new本当に必要な場合にのみ使用してください。だから、ただやってください:

test t("rrr", 8);
于 2013-03-26T12:59:46.487 に答える
1
test t=new test("rrr",8);

でなければなりません

//  v
test* t=new test("rrr",8);

つまり、名前に「*」が含まれているクラスの場合はどうでしょうか。

*ポインタを示すために使用されますが、クラスの名前ではありません。しかし、それは大きなトピックなので、これについていくつかの調査を行う必要があります。

于 2013-03-26T12:54:29.550 に答える
1
T* t = new T;
//     ^^^

このオブジェクト構築でnewが使用される場合、それはポインターの作成を示します。何をしているのかというと、メモリを動的に割り当てることですが、そうするつもりはなかったと思います。むしろ、典型的なスタック割り当てオブジェクトの構築は、次のように単純に行われます。

T t;

ポインタを作成してメモリを割り当てることを意図していたとしても、それは間違った方法で行いました。*コードに欠けていたシンボルを使用してポインターが作成されます。delete次に、作成したメモリの使用を終えたら、コードを覚えておく必要がありますdelete[]delete[]動的に割り当てられたアレイで使用されます。したがって、これはポインタを検索する方法です。

delete t;
于 2013-03-26T12:57:51.827 に答える
1

*は名前の一部ではなく、オブジェクトがポインタであることを示す修飾子です。ポインタは、実際のオブジェクトが格納されているメモリ内のある場所へのアドレスを保持する変数です。いくつかの基本:

int i = 5;
int * pI = &i;

int * pIつまり、intが保持されているメモリに配置するポインタを宣言する必要があります。&iつまり、変数へのポインタを取得する必要があります。したがって、pIは、iが格納されているメモリにアドレスを保持します。これで、ポインターを逆参照できます-ポインターの値を取得します。

int j = *pI;

ここで、pIが指すアドレスに移動し、その内容を取得するようにコンパイラーに指示します(pIはintへのポインターであるため、コンパイラーはそこにintがあると想定します)。

さて、あなたの例に戻りましょう。new演算子はオブジェクトに動的にメモリを割り当てるため、次のようになります。

new test("rrr", 8);

その結果、テストクラスにメモリが割り当てられ、パラメータ「rrr」と8を使用してコンストラクタが呼び出され、割り当てられたメモリへのポインタが返されます。そのため、変数に割り当てることはできません。testこの場合、new演算子は。を返しますtest *

このコードを試してください:

test * t = new test("rrr", 8);
于 2013-03-26T12:58:39.533 に答える
0

tポインタとして定義していません:

test* t=new test("rrr",8);

あるいは単に

test t = test("rrr",8);
于 2013-03-26T12:55:02.850 に答える