2010-06-03 125 views
0

在代码:构造被调用两次

//file main.cpp 
LINT a = "12"; 
LINT b = 3; 
a = "3";//WHY THIS LINE INVOKES CTOR? 


std::string t = "1"; 
//LINT a = t;//Err NO SUITABLE CONV FROM STRING TO LINT. Shouldn't ctor do it? 

//file LINT.h 
#pragma once 
#include "LINT_rep.h" 
class LINT 
{ 
private: 
    typedef LINT_rep value_type; 
    const value_type* my_data_; 
    template<class T> 
    void init_(const T&); 
public: 
    LINT(const char* = 0); 
    LINT(const std::string&); 
    LINT(const LINT&); 
    LINT(const long_long&); 
    LINT& operator=(const LINT&); 
    virtual ~LINT(void); 

    LINT operator+()const;    //DONE 
    LINT operator+(const LINT&)const;//DONE 
    LINT operator-()const;    //DONE 
    LINT operator-(const LINT&)const;//DONE 
    LINT operator*(const LINT&)const;//DONE 
    LINT operator/(const LINT&)const;///WAITS FOR APPROVAL 

    LINT& operator+=(const LINT&);//DONE 
    LINT& operator-=(const LINT&);//DONE 
    LINT& operator*=(const LINT&);//DONE 
    LINT operator/=(const LINT&);///WAITS FOR APPROVAL 
}; 

在被调用行号3,而不是分配optor构造函数。为什么?我愿意在某些服务器上卸载整个解决方案,否则很难将所有内容都放在这里。我也可以上传视频文件。另一件事是,当我实现这个任务optor我得到一个错误,这optor已经在obj文件?这是怎么回事?

+0

你可以发布你的“=” - 运营商的实施? – Simon 2010-06-03 11:38:24

+0

什么是LINT?为什么在'#pragma once'和'#include'之前LINT a =“12”'?从任何函数中改变一个变量是不可能的。 – 2010-06-03 11:39:50

+0

@Alexey Malistov对不起我的错我应该提到这个代码来自两个不同的文件。去解决它; – 2010-06-03 11:47:42

回答

7

你没有一个=运营商这需要的std::string(或char*)一RHS,所以,文字“3”正在建设中的LINT,然后分配使用=运营商。

编辑:至于在你的代码的第二个问题,你需要调用c_str()std::string得到的字符串char*缓冲区,然后同样的事情会发生,与您的文字3.

4

以下构造函数:

LINT(const char * = 0);

将被称为文字赋值“3”,因为它充当隐含的构造函数调用。如果您希望避免这种情况,请使用“显式”限定符前缀构造函数。

还为您希望分配的任何类型添加一个赋值运算符而无需隐式构造。

+0

提及'explicit'的+1。 – 2010-06-03 15:11:10

2

因为没有指定可以使用的赋值运算符。你可能需要这样的东西: LINT& operator=(const char*);

+0

@知道我了解你:错。编译器只会生成一个复制赋值运算符(即,其RHS与类本身类型相同(模常量&)。)转换赋值运算符永远不会由编译器生成。 – 2010-06-03 11:44:49

+0

@知道我了解你:但你确实提供了一个赋值运算符... – jpalecek 2010-06-03 11:44:59

+0

@德鲁霍尔我坐的更正了,你说得对,我错了,没有考虑到有转换被应用 – 2010-06-03 11:50:16

6

你的任务运营商需要一个LINT对象作为参数,但是当你说:

a = "3"; 

你交给的任务运算字符串文字,不掉毛的对象。编译器需要创建一个赋值操作可以使用的LINT对象,因此它会调用构造函数,它将const char *作为参数来执行此操作。

+0

@尼尔我应该明白你对我的问题的回答意味着我们从现在开始很酷,或者你刚刚犯了一个错误,没有意识到是谁的问题? – 2010-06-03 11:54:41

1

LINT& operator=(const LINT&); 没有LINT& operator=(const char *); 但有许多隐含的ctors。 因此调用implict ctor。

+0

那么不能将字符串转换为LINT? – 2010-06-03 11:53:12

+0

为什么我在尝试实现时遇到错误operator =()? – 2010-06-03 11:56:32

+0

@所有花费一些时间后,我决定变得简单,我刚刚创建了新的解决方案,我已经复制了这些文件(* .h&* .cpp)和surpr是惊喜没有更多的问题与不能将字符串转换为LINT和运算符=()没有更多的问题。 – 2010-06-04 18:42:26

0

您的LINT类定义的唯一赋值运算符是复制赋值运算符LINT& operator=(const LINT&)。因此,在第3行中,当您尝试为LINT对象分配静态C风格的字符串(const char [])时,编译器会识别出没有匹配的赋值运算符。

但是,允许编译器使用一个用户定义的类型转换来使呼叫工作。它选择LINT(const char *)构造函数将const char []转换为LINT对象,然后对其为右侧创建的临时LINT对象调用复制赋值运算符。

您可以通过提供LINT& operator=(const char*)赋值运算符来扩充您的复制赋值运算符来避免此临时错误。

2

构造

LINT(const char* = 0); 

充当转换构造赋值到char*(例如LINT a = "3")。如果将LINT对象分配给另一个LINT对象,则只会调用您的=()操作员。

LINT a; 
LINT& b = a 
LINT& c = LINT("4"); 

上面的表达式会调用您的=()-operator。