【问题标题】:Assignment operator overload / retrieve function赋值运算符重载/检索函数
【发布时间】:2014-12-09 00:51:13
【问题描述】:

我正在尝试从 BST 中检索一项用于课堂作业的项目。我不允许更改某些提供的代码。讲师在驱动程序中创建了一个检索功能(我无法更改),看起来像这样

static void retrieveItem(char *name)
{
    Data    const *data;

    cout << ">>> retrieve " << name << endl << endl;
    if (database->retrieve(name, data))
        cout << *data << endl;
    else
        cout << "not found" << endl;
    cout << endl;
}

它在 BST 类中调用的函数看起来像这样(到目前为止)。我无法更改函数调用的参数。

bool BST::retrieve(const char *key, Data const *& data) const
{
    int rIndex = 0;
    while (rIndex <= capacity)
    {
        if (strcmp(items[rIndex].data.getName(), key) == 0)
            {
            data = items[rIndex].data;
            return true;
            }
        else if (strcmp(items[rIndex].data.getName(), key) < 0)
            rIndex = (rIndex * 2) + 1;
        else if (strcmp(items[rIndex].data.getName(), key) > 0)
            rIndex = (rIndex * 2) + 2;
    }
    return false;
}

有一个名为 items 的结构数组,看起来像这样

struct Item
{
    Data    data;       // the data instance must be specified this way, NOT as a pointer
    bool    isEmpty = true;
    int     loc = 0;
};

Item *items;

最后我为数据类实现了以下赋值重载和复制构造函数(不能更改这个上的源文件)

Data::Data(const Data& source)
{
    strcpy(this->name, source.name);
}

Data& Data::operator=(const Data& data2)
{
    strcpy(this->name, data2.name);
    return *this;
}

如果我错了,请纠正我,但似乎他在驱动程序中检索函数的目标是使用键(名称)搜索数据对象,然后将其复制到发送给函数的数据参数中.不幸的是,这条线

data = items[rIndex].data;

在我的检索功能中不适用于 .或 ->] 我有 90% 的把握。是访问它的正确方法,但我收到错误“不存在从 'Data' 到 'const Data *' 的合适转换类型”

如果不使用赋值重载运算符,或者我的重载实现错误,我还能如何实现这一点?

【问题讨论】:

  • 一般来说你不是指 Data const *& data。当我看到类似的东西时,我很怀疑
  • @pm100 问题中的操作员指出,这是作业中提供的代码,无论多么可疑,他们都坚持使用它(我同意,说这有点奇怪最少)

标签: c++ oop pointers operator-overloading


【解决方案1】:
bool BST::retrieve(const char *key, Data const *& data) const

第二个参数是对指向 const Data 的指针的引用,因此您必须将其设置为指向items[rIndex].data指针,而不是其值。 p>

考虑以下

void foo(int & out)
{
    out = 42;
}

当它被这样调用时

// ...
int x = 0;
foo(x);
std::cout << x;

42 将被打印,因为 对 x 的引用 被传递到函数中。你的情况有点不同 - 你被传递了一个对指针的引用,这样调用者就可以以与上面类似的方式检索指向数据的指针,例如:

int x; // global
// ...
void foo(int *& out)
{
    x = 42;
    out = &x; // set out to pointer to x
}

int main()
{
    int * ptr = nullptr;
    foo(ptr); // foo will set ptr to the pointer to x
    std::cout << *ptr; // prints 42
}

同样,将打印 42。请注意使用一元引用 &amp; 和 deref * 运算符来获取指向 x 的指针并取消引用 ptr 以提取其值。

顺便说一句,如果不看更多课程,就无法判断您的Data::operator= 实现有多糟糕。就目前而言,它被破坏了,因为在内存的重叠区域上使用strcpy 是未定义的行为——如果有人试图将一个对象实例分配给它自己,就会发生这种情况(参见strcpy)。对于自赋值以外的情况,只有当赋值的目的地总是有足够的空间用于源中的字符串时,它才是正确的。否则,您将写入未分配的内存。此外,如果有任何其他成员变量,它们也需要复制。

【讨论】:

  • 那么我是否需要创建一个单独的指针变量并让它指向items[rIndex].data,然后将该指针用作第二个参数?赋值的目标是驱动函数中的数据对象,不是吗?并且没有其他成员
  • 问题出在BST::retrieve,而不是调用代码。
  • 我仍然不明白如何修复它
猜你喜欢
  • 1970-01-01
  • 2017-11-02
  • 2014-10-12
  • 2013-03-30
  • 2013-02-14
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多