CList< MyClass, MyClass& > MCList で、MyClassのオペレータ"="のエラー

[戻る]
fumi 2004/09/09(木) 15:43:14
下記のようなクラスを作成したのち、これをCListで使用しています。
class MyClass : public CObject
{
public:
    int test;

    MyClass() { test = 0; }
    MyClass( const MyClass& tmp ) { test = tmp.test; }
    virtual ~MyClass() {}

    MyClass& operator = ( const MyClass& tmp )
    {
        if(&tmp != this) {
            this->test = tmp.test;
        }
        return *this;
    }
};

CList< MyClass, MyClass& > MCList;

ある関数中で、下記のように使用しています。
MyClass Mine;
Mine = MCList.GetHead();

すると、ビルド時にLNKで、CListに関係して、「未解決の外部シンボル」"operator =" のエ
ラーがでてきます。
下記のように引数の"const"を消すとビルドが通り、問題なく動作します。
MyClass& operator = ( MyClass& tmp)

"const"を書かないことで、動作に問題はないのですが、なぜこんなエラーが出るのか気になり
ます。どなたか教えて頂けないでしょうか?
よろしくお願いします。

fumi 2004/09/09(木) 15:45:22
すみません。開発環境を書き忘れました。
OS:Windows2000
VC++ .net 2003
です。
よろしくお願いします。

Bosscat 2004/09/09(木) 16:32:01
>「未解決の外部シンボル」"operator ="
つまり、operator=() の実装が無い!
と怒っています。

そして、CObjectの定義には以下の関数が含まれます。
CObject(const CObject& objectSrc);              // no implementation
void operator=(const CObject& objectSrc);       // no implementation
<脱線>
本来こう書かれるべきでしょう
void operator=(const CObject& objectSrc)=0;

純粋仮想関数と同じ意味ですが、、、=0が付いていないのは
実装部分で何か魔法を使っているのでしょう・・・
</脱線>

なので、継承したクラスではこれらを実装しなければなりません。
そして今回コンパイラは、const有無によって、引数の型違いを指摘しているのでしょう。

ちなみに、VC6.0やBCCでは、constの評価が甘いので、コンパイルできるかもしれません。

fumi 2004/09/09(木) 23:43:38
Bosscatさん、ありがとうございました。
参考にさしてもらって、気づいたのですが、
最初に書いたクラスのように実装をクラス内に書けば、引数に"const"が付いてても、ビルドが
通る事が分かりました。

問題だったのは、
クラス内では、
MyClass& operator = ( const MyClass& );
として、実装を別に、
MyClass& MyClass::operator = ( const MyClass& tmp )
{
    if(&tmp != this) {
        this->test = tmp.test;
    }
    return *this;
}
と書いた時、引数に"const"を付けてると、最初に書いたエラーが出ます。

分かりにくくして、すみません。
よろしくお願いします。

Bosscat 2004/09/10(金) 09:36:20
すみません!
見当違いな回答でしたね!
constを取ると、コンパイルできるのですね!

ちょっと、調べて見ます。

επιστημη [E-Mail] [HomePage] 2004/09/10(金) 09:52:05
> CList< MyClass, MyClass& > MCList;

 CList< MyClass, const MyClass& > MCList;

としてないからかも。

Bosscat 2004/09/10(金) 10:07:03
VC7.0の環境が近くに無いので、
VC6.0で試したところ、、再現しません。。

VC7.0の環境に触れるのは、来週月曜になっちゃいます・・・・

ところで、実装を別にした場合、ファイルも別でしょうか?

6.0では、どちらでも問題ありませんでしたが、、
ただ、経験則から言わせてもらうと、問題が起きるソースとは思えないんですよね
第一感は、どうしても単純なリンクミスを疑ってしまいます。。

根拠:
const を付けた場合にコンパイルが通る。
つまり、CListのテンプレート展開も含めて
operator=(const MyClass&);の関数は適正である。

ならば、実装が無いだけ。 <−外部シンボルエラー

Bosscat 2004/09/10(金) 10:09:14
επιστημηさん
> CList< MyClass, const MyClass& > MCList;
データ部がconstなのは流石に不親切な気が・・・(w

επιστημη [E-Mail] [HomePage] 2004/09/10(金) 10:38:29
>> CList< MyClass, const MyClass& > MCList;
>データ部がconstなのは流石に不親切な気が・・・(w

はぁ? 第二templ.argはAdd,SetAtなどの引数の型ではないっけ? 

そもそもCListの定義自体:

template< class TYPE, class ARG_TYPE = const TYPE& >
class CList : public CObject { ... };

だから CList<X> とすればほっといても CList<X,const X&> ですけど。

fumi 2004/09/10(金) 11:35:41
[[解決]]
Bosscatさん、επιστημηさん、沢山の回答ありがとうございます。

Bosscatさん、質問の書き方が悪くてすみませんでした。実装は別のファイルにしていました。

お2人の回答参考にさして頂いて試してたところ、

CList< MyClass, const MyClass& > MCList;
または、
CList< MyClass > MCList;
と、書くことで、ビルドが通り、問題なく動作しました。

助言ありがとうございました。

Bosscat 2004/09/10(金) 12:17:10
>>> CList< MyClass, const MyClass& > MCList;
>>データ部がconstなのは流石に不親切な気が・・・(w

> はぁ? 第二templ.argはAdd,SetAtなどの引数の型ではないっけ? 

すみません。
私のCListの認識が間違っていただけです。

ただ、今見てきましたが、MSDN(2003)のサンプルでさえconstを意識していないですね。。

----抜粋------
template< class TYPE, class ARG_TYPE = const TYPE& >
class CList : public CObject
 :
<中略>
 :
// This code defines a list of ints.
CList<int,int> myList;

// This code defines a list of CStrings
CList<CString,CString&> myList;

// This code defines a list of MYTYPEs,
//NOTE: MYTYPE could be any struct, class or type definition
CList<MYTYPE,MYTYPE&> myList;
--------------

古いスレッドには追加発言できません。