【问题标题】:C++: constructor with user-defined typesC++:具有用户定义类型的构造函数
【发布时间】:2012-10-17 19:36:15
【问题描述】:

我正在尝试理解 C++ 中的类并开发一些我在 Python 中看到的类似类。代码如下:

#include <iostream>
#include <cmath>
using namespace std;

/*============================================================================*/
/* Define types
/*============================================================================*/
class none_type;
class bool_type;
class int_type;
struct identifier;

/*============================================================================*/
/* Define none type
/*============================================================================*/
class none_type {
  public:
    none_type()                  { /* constructor */ };
    ~none_type()                 { /* destructor */ };
}; /* none_type */

/*============================================================================*/
/* Define bool type
/*============================================================================*/
class bool_type {
  private:
    bool base;
  public:
    bool_type()                  { base = false; };
    ~bool_type()                 { /* destructor */ };
    bool_type(bool init)         { base = bool(init); };
    bool_type(int init)          { base = bool(init); };
    bool_type(long init)         { base = bool(init); };
    bool_type(float init)        { base = bool(init); };
    bool_type(double init)       { base = bool(init); };
    bool_type(bool_type init)    { base = bool(init.base); };
    bool_type(int_type init)     { base = bool(init.base); };
    int get()                    { cout << base << endl; };
}; /* bool_type */

/*============================================================================*/
/* Define int type
/*============================================================================*/
class int_type {
  private:
    long base;
  public:
    int_type()                   { base = 0; };
    ~int_type()                  { /* destructor */ };
    int_type(bool init)          { base = long(init); };
    int_type(int init)           { base = long(init); };
    int_type(long init)          { base = long(init); };
    int_type(float init)         { base = long(init); };
    int_type(double init)        { base = long(init); };
    int_type(bool_type init)     { base = long(init.base); };
    int_type(int_type init)      { base = long(init.base); };
    int get()                    { cout << base << endl; };
}; /* int_type */

当我尝试编译它时,g++ 告诉我所有使用我自己的类型的构造函数都是无效的。你能解释一下出了什么问题吗?我已经定义了类原型,我还应该做什么?提前致谢!

【问题讨论】:

  • 您不必将; 放在函数定义的末尾。并了解构造函数初始化列表...
  • 我删除了分号;这解决不了任何问题。似乎在很多情况下您必须在 C/C++ 中删除行尾的分号。
  • 您混淆了“定义”和“声明”。
  • 您不能在bool_type 类中使用bool_type,因为它还不知道需要多少内存。您需要一个指针或引用才能在其自身中使用该类。
  • 删除分号确实解决了一个问题。它有助于使您的程序看起来更专业,这样当其他人阅读您的代码时,他们更有可能相信您知道自己在做什么。它可能无法解决您所问的问题,但这就是弗拉德发表评论而不是回答的原因。

标签: c++ oop class methods constructor


【解决方案1】:

这个构造函数:

bool_type(int_type init)     { base = bool(init.base); };

无效,因为此时 int_type 不完整。

您必须将此构造函数实现移出类定义,直到 int_type 完成:

class bool_type {
  bool_type(int_type init);
};
class int_type {};
inline bool_type::bool_type(int_type init)     { base = bool(init.base); };

另一个问题是你的构造函数伪装成复制构造函数:

bool_type(bool_type init)    { base = bool(init.base); };

这里你有无限递归——因为init参数是一个副本——所以这个构造函数必须被调用来制作这个副本,但是这个构造函数的下一次调用有它自己的init参数必须被复制等等到无穷大或堆栈限制...

拷贝构造函数的正确定义如下:

bool_type(const bool_type& init)    { base = bool(init.base); };

必须使用常量引用,但在此你可以依赖编译器——它会为你生成复制构造函数——所以完全删除它。

【讨论】:

    【解决方案2】:

    除了“学习 C++”之外,很难给出具体的建议,但以下是如何在“普通”C++ 中设计您的课程:

    class int_type;
    
    class none_type { };
    
    class bool_type
    {
        bool base;
    public:
        bool_type() : base() { }
        explicit bool_type(bool init) : base(init) { }
        explicit bool_type(int_type const &);
    
        void print() const { std::cout << base << std::endl; }
        bool get() const { return base; }
    };
    
    class int_type
    {
        int base;
    public:
        int_type() : base() { }
        explicit int_type(int init) : base(init) { }
        explicit int_type(bool_type const & init) : base(init.get() ? 1 : 0) { }
    
        void print() const { std::cout << base << std::endl; }
        int get() const { return base; }
    };
    
    inline bool_type::bool_type(int_type const & init) : base(init.get()) { }
    

    【讨论】:

    • base 在这两种情况下都是私有的。因此,您需要一个访问器或转换运算符,以便在另一个构造函数中使用它们。
    【解决方案3】:

    G++ 已经告诉你,出了什么问题:

    错误:无效的构造函数;你的意思可能是“bool_type (const bool_type&)”

    您必须使用bool_type (const bool_type&amp;) 而不是bool_type (bool_type)。这样做的原因是,如果您按值传递对象,编译器会使用复制构造函数将其放入堆栈。因此,为了将bool_type 传递给复制构造函数bool_type(bool_type),它必须使用复制构造函数本身。这是不可能的。

    int_type(int_type) 也是如此。

    在构造函数'bool_type::bool_type(int_type)'中: 错误:“init”的类型不完整

    此时,G++ 不知道int_type 的样子。因为它不知道int_type 有一个base 成员,所以它不能使用它。只需声明构造函数:

    bool_type(int_type init);
    

    并在int_tpye声明后定义:

    ....
    class int_type {
    ....
    };
    
    ...
    inline bool_type(int_type init) { base = bool(init.base); }
    

    当您有较大的对象时,建议使用通过引用传递它们,因为通过值传递意味着复制堆栈上的对象。这比仅仅传递对这个大对象的引用要昂贵得多(对于大对象)。对于小物体,这无关紧要。

    最后一个错误:

    在构造函数'int_type::int_type(bool_type)'中: 错误:'bool bool_type::base' 是私有的

    您已将bool_type 中的成员base 声明为private:。这意味着,只允许bool_type 访问该成员。要获取base,您必须使用访问方法get()

    int_type(bool_type init)     { base = long(init.get()); }
    

    类比,你必须定义:

    inline bool_type(int_type init) { base = bool(init.get()); }
    

    最后,查看c++ 并按照书单。 C++ FAQ 也不错。

    编辑:我错过了,您的 get() 方法根本不是访问器。它们应该被定义为:

    class bool_type {
    public:
        bool get() const { return base; }
    ...
    };
    

    int_type::get() 也一样

    int get() const { return base; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多