遵循C++程序有什么问题
What is wrong with following C++ program?
为什么下面的C++代码会给出下面提到的错误?另外,为什么这不是用C++编写递归数据结构的惯用方式?这种写C++的方式有什么根本性的问题吗?
#include<iostream>
using namespace std;
class tree{
public:
virtual void inorder() {};
};
class emp_tree: public tree{
public:
void inorder(){
}
};
class non_emp_tree: public tree{
public:
tree left, right;
int val;
non_emp_tree(int v, tree l, tree r): val(v), left(l), right(r) {};
void inorder(){
left.inorder();
cout<<" "<<val<<" ";
right.inorder();
}
};
int main() {
tree leaf1 = non_emp_tree(1, emp_tree(), emp_tree());
tree leaf2 = non_emp_tree(3, emp_tree(), emp_tree());
tree root = non_emp_tree(2, leaf1, leaf2);
root.inorder();
return 0;
}
编译器给出的错误:(我无法理解其中的大部分(
/tmp/ccAjhirw.o: In function `main':
b_t.cpp:(.text+0x16e): undefined reference to `tree::inorder()'
/tmp/ccAjhirw.o: In function `tree::tree()':
b_t.cpp:(.text._ZN4treeC2Ev[_ZN4treeC5Ev]+0x9): undefined reference to `vtable for tree'
/tmp/ccAjhirw.o: In function `tree::tree(tree const&)':
b_t.cpp:(.text._ZN4treeC2ERKS_[_ZN4treeC5ERKS_]+0xd): undefined reference to `vtable for tree'
/tmp/ccAjhirw.o: In function `non_emp_tree::inorder()':
b_t.cpp:(.text._ZN12non_emp_tree7inorderEv[_ZN12non_emp_tree7inorderEv]+0x19): undefined reference to `tree::inorder()'
b_t.cpp:(.text._ZN12non_emp_tree7inorderEv[_ZN12non_emp_tree7inorderEv]+0x56): undefined reference to `tree::inorder()'
/tmp/ccAjhirw.o: In function `tree::tree(tree&&)':
b_t.cpp:(.text._ZN4treeC2EOS_[_ZN4treeC5EOS_]+0xd): undefined reference to `vtable for tree'
/tmp/ccAjhirw.o:(.rodata._ZTI12non_emp_tree[_ZTI12non_emp_tree]+0x10): undefined reference to `typeinfo for tree'
/tmp/ccAjhirw.o:(.rodata._ZTI8emp_tree[_ZTI8emp_tree]+0x10): undefined reference to `typeinfo for tree'
collect2: error: ld returned 1 exit status
编辑:我将virtual void inroder()
更改为virtual void inorder() {}
即空实现。但是我仍然没有得到想要的输出,似乎根、叶 1 和叶 2 都在调用树的无序而不是它们各自的无序。
您从未实现过tree::inorder
.
class tree{
public:
virtual void inorder();
};
在这里,您声称有这样一个函数 - 它的实现在哪里?
此外,这没有意义:
tree leaf1 = non_emp_tree(1, emp_tree(), emp_tree());
您正在将tree
的值设置为等于non_emp_tree
的值。这当然不会做任何有用的事情。
virtual void inorder(){}
应该在你的树类中,你缺少{}
首先,如果tree::inorder
是一个抽象方法,你需要正确地声明它:
class tree{
public:
virtual void inorder() = 0;
};
但是,这很快就会导致一堆其他问题,因为您正在左右切割对象!
tree leaf1 = non_emp_tree(1, emp_tree(), emp_tree());
此代码不可能产生您想要的效果。 non_emp_tree
包含tree
对象没有空间存储的成员变量。即使确实如此,您也无法保证对象的行为方式符合您的预期。在leaf1
上调用inorder
会尝试调用tree::inorder
,而不是non_emp_tree::inorder
,因为程序无法知道你打算在这里存储一个子类。
解决此问题的方法是对所有tree
对象使用指针。
#include<iostream>
#include<memory>
class tree{
public:
virtual void inorder() = 0;
virtual ~tree() = default;
};
class emp_tree: public tree{
public:
void inorder(){
}
};
class non_emp_tree: public tree{
public:
std::unique_ptr<tree> left, right;
int val;
non_emp_tree(int v, tree *l, tree *r): val(v), left(l), right(r) {};
void inorder(){
if(left) left->inorder();
std::cout<<" "<<val<<" ";
if(right) right->inorder();
}
};
int main() {
std::unique_ptr<tree> leaf1 = std::make_unique<non_emp_tree>(1, new emp_tree, new emp_tree);
std::unique_ptr<tree> leaf2 = std::make_unique<non_emp_tree>(3, new emp_tree, new emp_tree);
std::unique_ptr<tree> root = std::make_unique<non_emp_tree>(2, leaf1.release(), leaf2.release());
root->inorder();
return 0;
}
此代码的更好实现将完全避免使用裸new
,但这需要对代码进行一些重大重构。
你可能试图做的是使用多态性。但是,为此,您必须使用指向基的引用或指针,而不是基本身。即
#include<iostream>
#include<memory>
struct tree
{
virtual void inorder() = 0; // abstract: cannot be called
virtual ~tree() {}
};
struct emp_tree : tree
{
void inorder() override
{}
};
struct non_emp_tree : tree
{
std::unique_ptr<tree> left,right;
int val;
non_emp_tree(int v, tree*l, tree*r)
: left(l), right(r), val(v) {}
void inorder() override
{
left->inorder();
std::cout<<" "<<val<<" ";
right->inorder();
}
};
int main() {
auto leaf1 = new non_emp_tree(1, new emp_tree, new emp_tree);
auto leaf2 = new non_emp_tree(3, new emp_tree, new emp_tree);
auto root = new non_emp_tree(2, leaf1, leaf2);
root->inorder();
}
用叮叮当编译,产生1 2 3
。
类"tree"的"inorder"方法未实现,因此在调用此方法时会获得对此方法的未定义引用。
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了