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 文件的类没有 asterix,所有其他类都有)?我做错了什么?

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 文件的类没有 asterix,所有其他类都有)???

你肯定需要了解指针。test *并且test是 C++ 中两种完全不同的类型。这是具有这些类型的两个变量:

test t;
test* p;

在这里,t有 typetestpas type test*。我们描述test*为“指针test”。

您通常可以将指针视为对象的内存地址。所以在 中p,由于它是一个指针,我们可以存储 的内存地址t,即 a 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);

我们现在知道new test("rrr", 8)返回一个指向test(a test*) 的指针。但是,您正试图将其分配给一个test对象。你根本无法做到这一点。其中一个是地址,另一个是test. 因此编译器说“不存在合适的构造函数来从 转换test *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 回答