【问题标题】:C++ treating object* as int*C++ 将 object* 视为 int*
【发布时间】:2020-06-01 18:18:38
【问题描述】:

我有一些代码可以接受指向对象的指针,到目前为止,这一直运行良好,但是,经过一些清理(我的代码很乱,然后在大多数错误消失后清理),一个函数接受一个指针,现在将传递给它的指针视为int*

我检查过我确实传递了一个指针,但似乎无法弄清楚这一点。为什么会这样?

这是下面的一些代码(高度精简,我不确定是否允许我显示少量此代码,但我需要弄清楚这一点,如果不是很多,请见谅意义)。我已经删除了代码的敏感部分,坦率地说,我觉得发布时会遇到麻烦的部分。但是包含了错误的代码部分。

template <class T>
class TreeStructure {
    class TreeNode {

        public:
            T data;
            TreeNode<T> * parent;
            TreeNode<T> * left;
            TreeNode<T> * right;
            inline TreeNode(T d) : data(d), parent(0x0), left(0x0), right(0x0) {}
            inline TreeNode(T d,TreeNode<T>* p) : data(d), parent(p), left(0x0), right(0x0) {}
            inline TreeNode(T d,TreeNode<T>* p,TreeNode<T>* l,TreeNode<T>* r) : data(d), parent(p), left(l), right(r) {}
    };

    TreeNode<T>* root;

    // Recursive CRUD operations, used as helpers to public CRUD operations, _delete shown
    inline void _delete(TreeNode<T>* c) {
        if(c != 0x0) {
            _delete(c->left);  // This is where things go wrong, _delete compains of no valid conversion from 'int*' to 'TreeStructure::TreeNode<T>* [with T = int]'
            _delete(c->right);
            delete c;
            _size--;
            // Irrelevant operations down here
        }
    }

    public:
        inline bool remove(T d) {
            // Check if 'd' is in tree, return false if not, get pointer to containing node if so
            TreeNode<T>* node; // This is where we get the reference to the node. Code returns if data isn't found, so if we're here, we know we have a node.
            // _delete is never called if 'd' isn't in the tree, so we can assume its set to a node since we got this far
            _delete(node); // This call is fine, but the recursive calls in _delete fail
        }

};

当我调用remove() 时,remove() 又调用_delete(),当它是TreeNode&lt;int&gt;* 时,它抱怨节点是int*。而且我知道传递给_delete() 的任何内容都是TreeNode&lt;int&gt;*,即使递归调用,也可以防止NULL(如果为null,则为noop)。为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • TreeNode&lt;int&gt; 不是类型,TreeNode&lt;T&gt; 也不是。 TreeNode 不是模板。只需使用TreeNode。 (TreeStructure&lt;int&gt;::TreeNode 一种类型,但这不是模板。它是声明为模板类型的子类型的非模板类型。)此外,如果您使用 std::unique_ptr&lt;TreeNode&gt; 而不是原始指针。
  • TreeNode 不是int。指向TreeNode 的指针不是指向int 的指针。而且您不能将两者互换。为什么这令人惊讶?
  • 如果您创建了一个重现问题的最小完整示例而不是显示某些专有代码的部分摘录,那么回答起来会更容易。错误到底说了什么?而且,顺便说一句,你到底为什么使用0x0 而不是nullptr
  • 肯定是编译器在函数调用之前列出了关于这些声明的错误?您应该从错误列表的顶部开始。
  • 此代码在到达可疑行之前会给出大量编译时错误。请改正!

标签: c++ pointers type-conversion


【解决方案1】:

编译器不理解TreeNode&lt;T&gt; 是什么,因为它没有命名类型; TreeNode 不是模板。在您拥有TreeNode&lt;T&gt; 的任何地方使用TreeNode

TreeNode 隐式地从其外部模板类中获取T,因此甚至不需要以这种方式指定它。换句话说,TreeStructure&lt;int&gt;::TreeNodeTreeStructure&lt;std::string&gt;::TreeNode 已经是不同的类型了。

我不确定你为什么会得到你得到的具体错误,但我会假设编译器吐出的一堆错误中的某个地方是它抱怨TreeNode 不是模板,所以&lt;T&gt; 后缀没有意义。长期以来,C 和 C++ 编译器即使在遇到错误后仍会努力前进并尝试使事情正常运行,这是一个长期的传统。我认为理论上是,它一次可以引发的错误越多,您需要进行的编译器调用就越少,因为您可以在每次运行时修复多个错误。然而,在实践中,这意味着编译器会做出错误的假设,然后根据这些假设生成错误,因此它也会产生大量噪音。

在 C 和 C++ 编程中,始终注意 first 错误。之后的一切都可能是无用的噪音。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 2022-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多