【问题标题】:Why can't I make objects in C++ have data-members that are other objects?为什么我不能让 C++ 中的对象具有其他对象的数据成员?
【发布时间】:2011-05-19 09:31:45
【问题描述】:

有一天我很无聊,所以我做了这个库:

template <class X, class Y> class HASH
{
public:
HASH(X element, Y key)
{
    elements=new X[0];
    keys=new Y[0];
    keys[0]=key;
    elements[0]=element;
    num_elements=0;
};
~HASH ()
{
    delete[] elements;
    delete[] keys;
};
void Add(X element, Y key)
{
    for (int x=0; x<=num_elements; x++)
    {
        if (keys[x]==key)
        {
            throw(key);
        }
    }
    //make copy variables
    X *copy_elements=new X[num_elements];
    Y *copy_keys=new Y[num_elements];
    //copy all the elements
    for (int x=0; x<=num_elements; x++)
    {
        copy_elements[x]=elements[x];
        copy_keys[x]=keys[x];
    }
    //delete the originals
    delete[] elements;
    delete[] keys;
    //resize the originals
    elements=new X[num_elements+1];
    keys=new Y[num_elements+1];
    //copy everything back to the originals
    for (int x=0; x<=num_elements; x++)
    {
        elements[x]=copy_elements[x];
        keys[x]=copy_keys[x];
    }
    //delete the copies
    delete[] copy_keys;
    delete[] copy_elements;
    //increment num_elements
    num_elements++;
    //add the new elements
    elements[num_elements]=element;
    keys[num_elements]=key;
};
X operator [] (Y key)
{
    int num=0;
    for (int x=0; x<=num_elements; x++)
    {
        if (keys[x]==key)
        {
            num=x;
            break;
        }
    }
    return elements[num];
};
Y KeyNum(int x)
{
    return keys[x];
};
int NumElements()
{
    return num_elements;
};
private:
int num_elements;
X *elements;
Y *keys;
};

然后我对其进行了测试,它确实有效。所以现在我正在尝试创建一个实验,其源代码是这样的:

#include <hash.cpp>
#include <iostream>
using namespace std;

class OBJECT 
{
    public:
        OBJECT(string name, int number)
        {
            int_properties=new HASH <string, int>;
        };
        ~OBJECT()
        {
            delete int_properties;
        };
        HASH <string, int> *int_properties;
};

int main()
{
    OBJECT a("name", 5);
    return 0;
}

它正在返回错误:

Brain.cpp:在构造函数“OBJECT::OBJECT(std::string, int)”中: Brain.cpp:10:错误:没有匹配函数调用‘HASH<:basic_string std::char_traits>, std::allocator >, int>::HASH()’ /usr/include/hash.cpp:4:注意:候选者是:HASH::HASH(X, Y) [with X = std::basic_string, std ::allocator>, Y = int] /usr/include/hash.cpp:2: 注意:HASH<:basic_string std::char_traits>, std::allocator >, int>::HASH(const HASH, std::allocator >, int>&)

我做了很多测试,无论我做什么,我似乎都无法初始化一个对象,它是另一个对象的数据成员。我只是不明白为什么。

【问题讨论】:

  • 元素=新 X[0];这具有零大小。您不能访问 X[0] 它超出范围
  • 只是作为提示。尝试将 std::vector 用于您的元素和键。
  • @Martin 说了什么。尽管new T[n]n 为零时是合法的,但您对结果无能为力。

标签: c++ g++


【解决方案1】:
int_properties = new HASH <string, int>;

此行尝试调用class HASH&lt;string, int&gt; 的默认构造函数。也就是说,它尝试使用零个对象调用构造函数。但是没有这样的构造函数。你定义的构造函数是HASH&lt;string, int&gt;::HASH(string element, int key),它需要两个参数。

模板参数出现在&lt;&gt;。函数参数出现在()。不要混淆两者。

您可以通过添加一些函数参数来使用您定义的构造函数来解决此问题:

int_properties = new HASH<string, int> (name, number);

或通过修改或重载您的构造函数,使其可以接受零参数并成为默认构造函数。

template <class X, class Y> class HASH {
public:
  HASH();
  //...
};

template <class X, class Y> HASH<X,Y>::HASH() { /*...*/ }

【讨论】:

    【解决方案2】:

    在 C++ 中,对象当然可以是其他对象的数据成员。否则,您将只有由原始类型组成的类,而这几乎没有用处。

    这里的问题是您的class HASH 没有默认构造函数。

    如果你根本没有指定构造函数,那么编译器会为你创建一个默认构造函数。但是一旦定义了非默认构造函数,编译器将不再提供默认构造函数。

    因此,要么您必须将一个元素和一个键传递给您正在创建的 HASH 对象,要么您必须为 class HASH 提供一个默认构造函数,这可能会创建一个空哈希表。

    【讨论】:

      【解决方案3】:

      您的 HASH 类没有默认构造函数。 您的 OBJECT 构造函数应该是

      OBJECT(string name, int number)
      {
         int_properties=new HASH <string, int>(name, number);
      };
      

      【讨论】:

        【解决方案4】:

        没有默认构造函数:

        int_properties=new HASH <string, int>; // No constructor that takes zero arguments to HASH
        

        【讨论】:

          【解决方案5】:

          HASH 是一个模板类,不能直接实例化。

          【讨论】:

          • 什么意思?只要您指定模板参数,符合标准的编译器就必须实例化它。
          【解决方案6】:

          你声明了一个构造函数,它接受HASH&lt;X, Y&gt;的参数:

          HASH(X element, Y key)
          {
              elements=new X[0];
              keys=new Y[0];
              keys[0]=key;
              elements[0]=element;
              num_elements=0;
          };
          

          然后尝试在OBJECT::OBJECT中分配HASH&lt;string, int&gt;

          OBJECT(string name, int number)  
          {  
              int_properties=new HASH <string, int>;  
          };  
          

          你只需要将namenumber传递给HASH&lt;string, int&gt;的构造函数:

              int_properties=new HASH <string, int>(name, number);
          

          【讨论】:

          • @noah,那是因为您没有为 HASH 的成员分配任何内存。 new int[0] 返回一个零元素数组。我不确定你打算如何发展keyselements,但你现在的做法是不正确的。
          【解决方案7】:
          brain.cpp: In constructor ‘OBJECT::OBJECT(std::string, int)’: brain.cpp:10: error: no matching function for call to ‘HASH, std::allocator >, int>::HASH()’
          

          没错。您尚未为 HASH 类定义默认构造函数。

          【讨论】:

            猜你喜欢
            • 2019-03-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-24
            • 2014-06-15
            • 1970-01-01
            相关资源
            最近更新 更多