1

OK、コードを動作させることができましたが、何か問題があります。これは、演算子のオーバーロードと非メンバー関数のインライン化に関係しています。以下は、複素数オブジェクトを実装する非常に単純なプログラムです。

Complex.h に含まれる

using namespace std;

class Complex {
 private:
  double real;
  double imaginary;

 public:

  Complex(void);
  Complex(double r, double i);
  double getReal();
  double getImaginary();
  string toString();
};

inline Complex operator+(Complex lhs, Complex rhs);

...そしてComplex.ccで

#include <sstream>
#include <string>
#include "Complex.h"

using namespace std;

Complex::Complex(void)
{
...not important...
}

Complex::Complex(double r, double i)
{
  real = r;
  imaginary = i;
}

double Complex::getReal()
{
  return real;
}

double Complex::getImaginary()
{
  return imaginary;
}

string Complex::toString()
{
...what you would expect, not important here...
}


inline Complex operator+(Complex lhs, Complex rhs)
{
  double result_real = lhs.getReal() + rhs.getReal();
  double result_imaginary = lhs.getImaginary() + rhs.getImaginary();

  Complex result(result_real, result_imaginary);

  return(result);
}

そして最後に plus_overload_test.cc に

using namespace std;

#include <iostream>
#include "Complex.h"

int main(void)
{
  Complex c1(1.0,3.0);
  Complex c2(2.5,-5.2);

  Complex c3 = c1 + c2;

  cout << "c3 is " << c3.toString() << endl;

  return(0);
}

これをリンクするメイクファイルを使用して g++ でコンパイルすると、次のエラーが発生します。

plus_overload_test.cc:(.text+0x5a): undefined reference to `operator+(Complex, Complex)'

Complex.h と Complex.cc の operator+ の前から「インライン」を削除すると、すべてがコンパイルされ、正常に動作します。インライン修飾子がこのエラーを引き起こすのはなぜですか? 全員、例えば:

演算子のオーバーロード

http://en.cppreference.com/w/cpp/language/operators

二項演算子をオーバーロードするには、関数を非メンバーでインラインにすることをお勧めしているようです。では、インラインにするとエラーが発生するのはなぜですか?

そして、はい、最新のコンパイラがこれを処理する必要があるため、インライン修飾子がニシンである可能性があることを認識しています。しかし、私は好奇心のままです。

乾杯!

4

1 に答える 1

2

関数は、それが使用されるすべてのファイルで定義するinline必要があります。

標準の正確な文言が必要な場合 (§7.1.2/4):

インライン関数は、それが使用されるすべての翻訳単位で定義され、すべての場合でまったく同じ定義を持つものとします。

とマークinlineされていますが、1 つの翻訳単位でしか定義されていないため、コンパイラとの契約の側面を満たしていませんでした (いわば)。

于 2013-11-16T04:14:05.610 に答える