Некоторые заметки, которые могут вас заинтересовать:
#include <string>
#include <iostream>
namespace humans
{
class person
{
private:
// certainly never write using namespace::thing in header files.
// if you are going to be using a type, do it in a very confined scope, in a cpp file
std::string fname, lname;
double salary;
public:
person(std::string, std::string, double); // ctor declaration
// you neither need or want a destructor for this class.
// if you define a destructor, you must also define copy & assignment
// operators. See rule of 5, 3 or none.
// define a way to see the salary
double get_salary() const { return salary; }
// there is no such thing as a person plus a person.
// avoid nonsensical mathematical abstractions
// double operator+(person);
};
// let's also provide a free function to get_salary, because it can be useful in ADL
auto get_salary(person const & p) -> decltype(p.get_salary())
{
return p.get_salary();
}
// salary_burden does not need to be a friend now that we
// have a way to get the salary. Since there is a free function available
// in the namespace of person, we could abstract this function a little more!
auto salary_burden(person const& x, person const& y) -> decltype(get_salary(x) + get_salary(y))
{
return get_salary(x) + get_salary(y);
}
}
// indeed in c++17 we could also abstract this concept completely...
template<class...Things>
auto salary_burden(Things&&...things)
{
// here whatever namespace Things is in, this namespace will be
// searched for a function called get_salary(Thing[&&|const&|&])
return (get_salary(things) + ...);
}
namespace non_humans
{
struct robot{};
// note that a robot does not have a get_salary() member
auto get_salary(robot const&) -> double { return 5; }
}
int main()
{
auto alice = humans::person("alice", "the programmer", 20000);
auto bob = humans::person("bob", "the builder", 10000);
auto robby1 = non_humans::robot();
auto robby2 = non_humans::robot();
auto robby3 = non_humans::robot();
// calls salary_burden(person const& x, person const& y)
std::cout << salary_burden(alice, bob) << '\n';
// calls auto salary_burden(Things&&...things)
std::cout << salary_burden(alice, bob, robby1, robby2, robby3) << '\n';
}