实现从Java到C++的跨越

3 c++

正如主题所说我对c ++很新,但我对java有一些经验.为了开始学习c ++,我有了一个简单的命令行计算器(不是非常原始的)的想法.我想要做的是将数字和运算符存储在二叉树中.

#include <iostream>
using namespace std;

class Node
{
  bool leaf;
  double num;
  char oper;
  Node* pLNode;
  Node* pRNode;

public:

  Node(double n)
  {
    num = n;
    leaf = true;
    pLNode = 0;
    pRNode = 0;
  }

  Node(char o, Node lNode, Node rNode)
  {
    oper = o;
    pLNode = &lNode;
    pRNode = &rNode;
    leaf = false;
  }

  bool isLeaf()
  {
    return leaf;
  }

  double getNumber()
  {
    return num;
  }

  char getOperator()
  {
    return oper;
  }

  Node* getLeftNodePointer()
  {
    return pLNode;
  }

  Node* getRightNodePointer()
  {
    return pRNode;
  }

  //debug function
  void dump()
  {
    cout << endl << "**** Node Dump ****" << endl;
    cout << "oper: " << oper << endl;
    cout << "num: " << num << endl;
    cout << "leaf: " << leaf << endl;
    cout << "*******************" << endl << endl;
  }

};

class CalcTree
{
  Node* pRootNode;
  Node* pCurrentNode;
public:

  Node* getRootNodePointer()
  {
    return pRootNode;
  }

  Node* getCurrentNodePointer()
  {
    return pCurrentNode;
  }

  void setRootNode(Node node)
  {
    pRootNode = &node;
  }

  void setCurrentNode(Node node)
  {
    pCurrentNode = &node;
  }

  double calculateTree()
  {
    return calculateTree(pRootNode);
  }

private:

  double calculateTree(Node* nodePointer)
  {
    if(nodePointer->isLeaf())
    {
      return nodePointer->getNumber();
    }
    else
    {
      Node* leftNodePointer = nodePointer->getLeftNodePointer();
      Node* rightNodePointer = nodePointer->getRightNodePointer();
      char oper = nodePointer->getOperator();

      if(oper == '+')
      {
    return calculateTree(leftNodePointer) + calculateTree(rightNodePointer);
      }
      else if(oper == '-')
      {
    return calculateTree(leftNodePointer) - calculateTree(rightNodePointer);
      } 
      else if(oper == '*')
      {
    return calculateTree(leftNodePointer) * calculateTree(rightNodePointer);
      }
      else if(oper == '/')
      {
    return calculateTree(leftNodePointer) / calculateTree(rightNodePointer);
      }
    }
  }
};

int main(int argc, char* argv[])
{
  CalcTree tree;
  tree.setRootNode(Node('+', Node(1), Node(534)));
  cout << tree.calculateTree() << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我对这段代码有几个问题:

  1. 这编译但不执行预期的操作.似乎在tree.setRootNode之后(Node('+',Node(1),Node(534))); 在main中,rightnode被正确初始化,但leftnode却没有.编译并运行它为我打印534(gcc,freebsd).这有什么不对?

  2. 在c ++中似乎人们更喜欢在类之外定义类的成员,比如

    A类{public:void member(); };

    A :: member(){std :: cout <<"Hello world"<< std :: endl;}

    这是为什么?

  3. 我非常喜欢关于c ++约定的一些指针(命名,缩进等)

  4. 我习惯用eclipse编写java代码.我正在使用emacs来学习c ++.有人可以告诉我一个好的(免费)c ++ ide,或者我应该像真人一样坚持和坚持使用emacs?:)

gim*_*mpf 5

  • 首先,我只能建议你看看"Accelerated C++"这本书.它将启动您进入STL和C++ 风格,并可以为您节省一年的糟糕体验.(如果你决定深入研究,那里有很多关于C++的非常好的文献.)

  • C++不在堆上使用自动内存管理.您正在存储指向临时指针的指针.您的程序尝试访问被破坏的对象时不正确.无论喜欢与否,您都必须先了解对象的生命周期.通过使用值语义(不存储指针,但存储对象的副本),您可以在简单的情况下简化这一部分.

  • 据报道,Eclipse/CDT在Linux上相当不错.在Windows上,使用Microsoft Visual C++ Express Edition可以更轻松地完成.当你掌握了基础知识后,稍后切换对你来说没问题.

  • 首选定义类本身之外的成员是首选,因为我们通常会分割标题和实现文件.在标题中,您尝试不公开任何不必要的信息,并且还要减少代码大小,这是编译时间的简单问题.但是对于许多现代编程技术(比如使用模板元编程),这是不能使用的,因此相当一些C++代码在内联定义的方向上移动.