-5

So this is not about a problem I faced but about a question in an exam I am not able to answer properly.

I have the following class:

template<class T>
class Server {
protected:
  std::vector<T> requests;
public:
 Server() = default;
 Server(const Server& other) = default;
 ~Server() = default;
 Server(const std::vector<T>& vec);
 Server& operator=(const Server<T>& other) = default;
 Server& operator+=(const T& request);
 Server& operator-=(const T& request);
 void operator()();
 std::size_t numRequests() const;
 friend Server<T> operator+(const Server<T>& a, const Server<T>& b );
 friend std::ostream& operator<<(std::ostream&, const Server<T>&);
};
template<class T>
Server<T> operator+(const Server<T>& a, const Server<T>& b );
template<class T>
std::ostream& operator<<(std::ostream&, const Server<T>&);

Now, I create a class named LimitedNamedServer, the difference between the classes are that LimitedNamedServerobjects has a maximum capacity of requests and a name.

This is what it looks like:

template<class T>
LimitedNamedServer : public Server<T> {
 std::string name;
 std::size_t maxLimit;
public:
 LimitedNamedServer(const char* name, std::size_t limit) : Server<T>(), name(name), maxLimit(limit) {}
 LimitedNamedServer(const LimitedNamedServer& other) = default;
 ~LimitedNamedServer() = default;
 LimitedNamedServer(const char* name, std::size_t limit, const std::vector<T>& vec) : Server<T>(vec), name(name), maxLimit(limit) {
if(requests.size() > maxLimit) {
throw OverLimit();
 }
}
 LimitedNamedServer& operator=(const LimitedNamedServer<T>& other) = default;
 LimitedNamedServer& operator+=(const T& request) {
 if(numRequests()>=maxLimit) {
   throw OverLimit();
}
else {
 requests.push_back(request);
}
 return *this;
}
};

Now, the problem is as follows:

Let s1,s2 and s3 be three objects from the class LimitedNamedServer. Why will the following code not compile, how can this problem be fixed:

s1=s2+s3

I have no idea why this is not supposed to compile. From what I know the + operator I defined for the class Server can also be used on objects from the class LimitedNamedServer. My best guess is that it happens due to that inside the implementation of +, I create a new Server but not a LimitedNamedServer, and that the error occurs because s1 expects to recieve a LimitedNamedServer object while this is not the object returned.

This is just a guess however, can someone please explain the reason for that?

איתן לוי
  • 433
  • 1
  • 3
  • 9
  • 1
    What exactly is the error? And please format your code. – Carcigenicate Jul 20 '19 at 18:18
  • Lets start with the error – Stefan Jul 20 '19 at 18:18
  • I wrote that this is a question from a written exam, I did not run the code myself. – איתן לוי Jul 20 '19 at 18:18
  • 1
    One thing is that `LimitedNamedServer` is missing `class` keyword, but really, the easiest way would be to actually compile it and check the real errors. – Yksisarvinen Jul 20 '19 at 18:20
  • 1
    Can you indent your code properly please so that we can read it? – Lightness Races in Orbit Jul 20 '19 at 18:20
  • 2
    Just compile it and you'll see immediately what the problem is. You'll need to actually finish the program first, though, because loads of code is missing here. – Lightness Races in Orbit Jul 20 '19 at 18:20
  • 5
    @איתן לוי The first step then would be to run it to produce an error. Trying to guess isn't a good use of time. – Carcigenicate Jul 20 '19 at 18:20
  • Why do you think your guess is wrong? – Lightness Races in Orbit Jul 20 '19 at 18:22
  • 1
    As you already know, your operator + returns a `Server` and not a `LimitedNamedServer`. You probably want to define an operator plus that use and returns `LimitedNamedServer` as `s1`, `s2` and `s3` are of that type. – Phil1970 Jul 20 '19 at 18:26
  • Should we assume that somehow poltergeists stole the `class` that should be between `template` and `LimitedNameServer` at the very top of the second paste ? – WhozCraig Jul 20 '19 at 18:56
  • @איתןלוי I would point out that this is a question from a written exam. Once the exam is over, the natural thing (for me, at least) would be to feed the code to a compiler. The compiler would tell me why that line does not compile, and this answer would be faster than any other resource. (If the compiler's error message is tough to understand, then that could be a question to ask here. But start with the source; ask the compiler why it does not like that line.) – JaMiT Jul 20 '19 at 19:24
  • I wonder, if all the downvoters understand the question and have an answer. It is not so easy. Besides the incomplete code (which I completed in 5 minutes) and some errors, including lookup rules for in/dependent names and missing virtual qualifier and others. The basic problem is that the operator + in the class needs only one parameter and using that operator a Type Server will be returned by the operator +, and there is no assignement to the derived class possible. Only Phil1970 understood the problem . . . +1 – A M Jul 20 '19 at 20:13

1 Answers1

2

Try to explain to yourself why it should compile instead…

Given that operator + works with Server ask yourself what would happen to name and maxLimit if that code would be allowed to compile.

Hint: What is object slicing?

Thus as you already know, you need to defined an operator + for LimitedNamedServer too. Typical implementation would be:

template <class T>
LimitedNamedServer<T> operator+(const LimitedNamedServer<T> &lhs, const LimitedNamedServer<T> &rhs)
{
    LimitedNamedServer result = lhs;
    result += rhs;
    return result;
}

Written that way, you reuse existing code and don't need to give friendship.

Phil1970
  • 2,605
  • 2
  • 14
  • 15
  • 1
    This can be further enhanced by making the first argument by-value rather than const-reference and removing `result` entirely. The resulting code then just becomes `lhs += rhs; return lhs;` – WhozCraig Jul 20 '19 at 21:06