为什么以下C ++代码会给出下面提到的错误?另外,为什么这不是用C ++编写递归数据结构的惯用方法呢?这种编写C ++的方式是否存在根本性的错误?
package GUI;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class MainWindow extends JFrame {
private Container mainPane;
private JButton mainButton;
private JButton clientButton;
private JButton residentialButton;
private JButton commercialButton;
private Vector<JPanel> panelList;
public MainWindow() {
panelList = new Vector<JPanel>(4);
JPanel tempPanel = createMainPanel();
panelList.add(tempPanel);
ClientWindow clientWindow = new ClientWindow();
panelList.add(clientWindow.createClientPanel());
ResidentialWindow residentialWindow = new ResidentialWindow();
panelList.add(residentialWindow.createResidentialPanel());
CommercialWindow commercialWindow = new CommercialWindow();
panelList.add(commercialWindow.createCommercialPanel());
}
public void createWindow() {
this.setTitle("Management Software");
int frameWidth = 936;
int frameHeight = 592;
double screenWidth = this.getToolkit().getScreenSize().getWidth();
double screenHeight = this.getToolkit().getScreenSize().getHeight();
int startX = (int) (screenWidth / 2 - frameWidth / 2);
int startY = (int) (screenHeight / 2 - frameHeight / 2);
this.setSize(frameWidth, frameHeight);
this.setLocation(startX, startY);
mainPane = this.getContentPane();
mainPane.setLayout(new BorderLayout(5, 5));
JPanel buttonPanel = new JPanel(new GridLayout(1, 4));
Border buttonEdge = BorderFactory.createRaisedBevelBorder();
mainButton = new JButton("Main");
mainButton.setBorder(buttonEdge);
mainButton.addActionListener(new ButtonListener());
buttonPanel.add(mainButton);
clientButton = new JButton("Client");
clientButton.setBorder(buttonEdge);
clientButton.addActionListener(new ButtonListener());
buttonPanel.add(clientButton);
residentialButton = new JButton("Residential");
residentialButton.setBorder(buttonEdge);
residentialButton.addActionListener(new ButtonListener());
buttonPanel.add(residentialButton);
commercialButton = new JButton("Commercial");
commercialButton.setBorder(buttonEdge);
commercialButton.addActionListener(new ButtonListener());
buttonPanel.add(commercialButton);
mainPane.add(buttonPanel, BorderLayout.NORTH);
mainPane.add(panelList.get(0), BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
private JPanel createMainPanel() {
JPanel mainPanel = new JPanel();
JLabel mainL = new JLabel("The Main Screen",SwingConstants.CENTER);
mainL.setForeground(Color.blue);
mainL.setFont(new Font("Copperplate Gothic Bold",Font.BOLD,48));
mainPanel.add(mainL);
return mainPanel;
}
/***************************** INNER CLASSES *****************************/
private JPanel tp;
@Override
public void actionPerformed(ActionEvent e){
for(int i = 0; i < panelList.size(); i++){
tp = panelList.get(i);
mainPane.remove(tp);
tp.setVisible(false);
}
if(e.getSource() == mainButton){
tp = panelList.get(0);
mainPane.add(tp,BorderLayout.CENTER);
tp.setVisible(true);
}
if(e.getSource() == clientButton){
tp = panelList.get(1);
mainPane.add(tp,BorderLayout.CENTER);
tp.setVisible(true);
}
if(e.getSource() == residentialButton){
tp = panelList.get(2);
mainPane.add(tp,BorderLayout.CENTER);
tp.setVisible(true);
}
if(e.getSource() == commercialButton){
tp = panelList.get(3);
mainPane.add(tp,BorderLayout.CENTER);
tp.setVisible(true);
}
}
}
}
编译器给出的错误:(我无法理解其中的大部分内容)
#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()
,即空实现。但是我仍然没有获得所需的输出,似乎root,leaf1和leaf2都是调用树而不是它们各自的inorders。
答案 0 :(得分:3)
您从未实施过05/04/2017
。
tree::inorder
在这里你声称有这样的功能 - 它的实现在哪里?
此外,这没有意义:
class tree{
public:
virtual void inorder();
};
您将tree leaf1 = non_emp_tree(1, emp_tree(), emp_tree());
的值设置为等于tree
的值。这肯定不会有用。
答案 1 :(得分:1)
virtual void inorder(){}
应该在你缺少的树类中{}
答案 2 :(得分:1)
您可能尝试做的是使用多态性。但是,为此必须使用引用或指针,而不是基本身。即。
#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();
}
使用clang编译,生成1 2 3
。
答案 3 :(得分:1)
首先,如果tree::inorder
是一个抽象方法,你需要正确地声明它:
class tree{
public:
virtual void inorder() = 0;
};
然而,这很快就会导致一系列其他问题,因为你正在左右切割你的对象!
tree leaf1 = non_emp_tree(1, emp_tree(), emp_tree());
此代码不可能具有您想要的效果。 non_emp_tree
包含tree
对象无法存储空间的成员变量。即使它确实如此,您也无法保证对象的行为符合您的预期。在inorder
上leaf1
的调用会尝试调用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
,但这需要对代码进行一些重大的重构。
答案 4 :(得分:0)
&#34; inorder&#34;类&#34;树的方法&#34;未实现,因此在调用它时会得到对此方法的未定义引用。