【问题标题】:no suitable constructor exists to convert from "test *" to "test", constructor,不存在合适的构造函数来将“test *”转换为“test”,构造函数,
【发布时间】:2013-03-16 06:39:03
【问题描述】:

我是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,所有其他类都有)?我做错了什么?

【问题讨论】:

    标签: c++ object pointers constructor instance


    【解决方案1】:

    我想您来自 Java/C# 背景。 t 这里不是引用类型,而是值类型。 new 返回一个指向对象的指针。因此,您需要以下任何一项:

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

    如果您还不熟悉指针,那么绝对不要使用最后一个!但是理解指针的语义是相当关键的。我建议您阅读教科书中的相关章节...

    【讨论】:

    • 很好,你的回答比我的要好:) +1
    • tnx 很多。你猜对了,我是用java和c#编程的,所以我在c++上有点挣扎:) ....
    • @klo 如果你尝试像编写 Java 一样编写 C++,你会犯很多错误。它们根本不是很相似。
    • “我想你是从 Java 来的”这很痛苦,但无论如何感谢大声笑,我在变量名之前缺少 * 运算符
    【解决方案2】:

    那么,名称中带有“*”的类是怎么回事(例如,没有 .cpp 文件的类没有 asterix,所有其他类都有)???

    您肯定需要了解指针。 test *test 在 C++ 中是两种完全不同的类型。以下是这些类型的两个变量:

    test t;
    test* p;
    

    这里,t 的类型为 testp 的类型为 test*。我们将test* 描述为“指向test 的指针”。

    您通常可以将指针视为对象的内存地址。所以在p中,既然是指针,我们可以存储t的内存地址,也就是test。要获取对象的地址,我们使用一元 &amp; 运算符,如下所示:

    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 的指针(一个test*)。但是,您尝试将其分配给 test 对象。你根本无法做到这一点。其中一个是地址,另一个是test。因此编译器说“不存在合适的构造函数来从test * 转换为test。”现在说得通了,不是吗?

    相反,您应该更喜欢使用自动存储期限。仅在您确实需要时才使用new。所以就这样做吧:

    test t("rrr", 8);
    

    【讨论】:

      【解决方案3】:
      test t=new test("rrr",8);
      

      必须

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

      那么,名称中带有“*”的类是怎么回事

      * 用来表示指针,不在类名中。但这是一个很大的话题,所以你应该对此进行一些研究。

      【讨论】:

        【解决方案4】:

        * 不是名称的一部分,它是一个修饰符,表示该对象是一个指针。指针是一个变量,它保存指向内存中某个位置的地址,其中存储了实际对象。一些基础知识:

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

        int * pI 意味着,您要声明一个指针以放置在内存中,其中保存了一个 int。 &amp;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);
        

        【讨论】:

          【解决方案5】:
          T* t = new T;
          //     ^^^
          

          在此对象构造中使用 new 时,表示创建了一个指针。正在做的是动态分配内存,我敢肯定你不是故意的。相反,典型的堆栈分配对象构造是这样完成的:

          T t;
          

          即使您打算创建一个指针并分配内存,但您做错了。使用您的代码中缺少的 * 符号创建一个指针。其次,当你使用完你创建的内存后,你必须记住delete/delete[]你的代码。 delete[] 用于动态分配的数组。所以这就是它会如何寻找你的指针:

          delete t;
          

          【讨论】:

            【解决方案6】:

            您没有将t 定义为指针:

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

            或者只是

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-29
              • 2012-07-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多