简体   繁体   English

在库中使用非成员函数来定义/声明比较运算符的重载?

[英]Where to define/declare overload of comparison operators as non-member functions in a library?

Let's imagine that I have a class named "Myclass" for which it makes sense to overload the comparison operators. 让我们假设我有一个名为“Myclass”的类,为比较运算符重载是有意义的。 I need to put this class into a library named "libmyclass", against which I want to compile/link a program named "myprog". 我需要把这个类放到一个名为“libmyclass”的库中,我想要编译/链接一个名为“myprog”的程序。

Following advice , I chose to overload the comparison operators as non-member functions. 根据建议 ,我选择将比较运算符作为非成员函数重载。 I chose to declare them in the header file and define them in the implementation file, but they are not found at the linking step: "undefined reference to `operator<(...)'" (see below). 我选择在头文件中声明它们并在实现文件中定义它们,但是在链接步骤中找不到它们:“未定义引用`operator <(...)'”(见下文)。 What should I do to fix this? 我该怎么做才能解决这个问题?

Here is the file "myclass.h": 这是文件“myclass.h”:

#ifndef MYCLASS_H
#define MYCLASS_H

#include <cstdlib>

#include <string>
using namespace std;

class Myclass {
private:
  size_t x_;
public:
  Myclass(void);
  Myclass(const size_t & x);
  const size_t & GetValue(void) const { return x_; };
};

bool operator==(const Myclass& lhs, const Myclass& rhs);
bool operator!=(const Myclass& lhs, const Myclass& rhs);
bool operator< (const Myclass& lhs, const Myclass& rhs);
bool operator> (const Myclass& lhs, const Myclass& rhs);
bool operator<=(const Myclass& lhs, const Myclass& rhs);
bool operator>=(const Myclass& lhs, const Myclass& rhs);

#endif //MYCLASS_H

Here is the file "myclass.cc": 这是文件“myclass.cc”:

#include "myclass.h"

Myclass::Myclass(void)
{
}

Myclass::Myclass(const size_t & x)
{
  x_ = x;
}

inline bool operator==(const Myclass& lhs, const Myclass& rhs)
{
  return(lhs.GetValue() == rhs.GetValue());
}

inline bool operator< (const Myclass& lhs, const Myclass& rhs)
{
  return(lhs.GetValue() < rhs.GetValue());
}

inline bool operator!=(const Myclass& lhs, const Myclass& rhs){return !operator==(lhs,rhs);};
inline bool operator> (const Myclass& lhs, const Myclass& rhs){return  operator< (rhs,lhs);};
inline bool operator<=(const Myclass& lhs, const Myclass& rhs){return !operator> (lhs,rhs);};
inline bool operator>=(const Myclass& lhs, const Myclass& rhs){return !operator< (lhs,rhs);};

Here is the file "myprog.c": 这是文件“myprog.c”:

#include <cstdlib>

#include <iostream>
using namespace std;

#include "myclass.h"

int main (int argc, char ** argv)
{
  Myclass * pt_obj1 = new Myclass(1);
  Myclass * pt_obj2 = new Myclass(2);
  if (*pt_obj1 < *pt_obj2)
    cout << "obj1 < obj2" << endl;
  else
    cout << "obj1 >= obj2" << endl;
  delete pt_obj1;
  delete pt_obj2;
  return EXIT_SUCCESS;
}

Here is the file "Makefile_lib": 这是文件“Makefile_lib”:

PROJECT=libmyclass.a
SOURCES=myclass.cc
CC=g++
CFLAGS=-Wall -Wextra -g

OBJECTS=$(SOURCES:.cc=.o)

all: $(PROJECT)

$(PROJECT): $(OBJECTS)
            ar -cvq $(PROJECT) $(OBJECTS)

.cc.o:
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        rm -f $(OBJECTS) $(PROJECT)

Here is the file "Makefile_exe": 这是文件“Makefile_exe”:

PROJECT=myprog
SOURCES=myprog.cc
LIB=libmyclass.a
CC=g++
CFLAGS=-Wall -Wextra -g

OBJECTS=$(SOURCES:.cc=.o)

all: $(PROJECT)

$(PROJECT): $(OBJECTS) $(LIB)
            $(CC) $(OBJECTS) -L. -lmyclass

.cc.o:
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        rm -f $(OBJECTS) $(PROJECT)

Finally, here are the commands I used and error I got: 最后,这是我使用的命令和错误:

$ make -f Makefile_lib clean
rm -f myclass.o libmyclass.a
$ make -f Makefile_lib
g++ -Wall -Wextra -g -c myclass.cc -o myclass.o
ar -cvq libmyclass.a myclass.o
a - myclass.o
$ make -f Makefile_exe clean
rm -f myprog.o myprog
$ make -f Makefile_exe
g++ -Wall -Wextra -g -c myprog.cc -o myprog.o
myprog.cc:8: warning: unused parameter ‘argc’
myprog.cc:8: warning: unused parameter ‘argv’
g++ myprog.o -L. -lmyclass
myprog.o: In function `main':
/home/me/src/myprog.cc:12: undefined reference to `operator<(Myclass const&, Myclass const&)'
collect2: ld returned 1 exit status
make: *** [myprog] Error 1

您应该将所有inline定义移动到声明下面的头文件中

Your code contradicts itself. 你的代码与自己相矛盾。

When myprog.c is compiled, operator<(Myclass const&, Myclass const&) can't be inlined . 编译myprog.c无法内联 operator<(Myclass const&, Myclass const&) The definition is nowhere to be seen. 这个定义无处可见。

When myclass.cc is compiled, operator<(Myclass const&, Myclass const&) isn't generated for the linker because you're promising that it will be inlined. 编译myclass.cc不会为链接器生成 operator<(Myclass const&, Myclass const&) 因为您承诺它将被内联。

The solution is to either remove the inline for those functions, or move the definitions to a header so they may truly be inlined. 解决方案是删除这些函数的inline ,或将定义移动到标题,以便它们可以真正内联。

The inline are to be put in the .h file 内联将放在.h文件中

or remove the inline in the .cpp file 或删除.cpp文件中的内联

and probably 可能

inline bool operator!=(const Myclass& lhs, const Myclass& rhs){return !(lhs==rhs);}

is simpler than the operator form. 比运算符形式更简单。

and no need to put an ; 而且不需要放; after a function definition. 在函数定义之后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM