Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not instantiate a class whose constructor is private in a friend class?

I have two classes; Salary that is intended to hold information and calculations regarding the salary of an employee and Employee that has an object of type class Salary and some members like name and address of the employee...

  • What I want to do is to prevent class Salary from being instantiated except by class Employee. So I declared the constructors of Salary private and made Employee a friend of Salary. But I get errors:

    class Employee;
    
    class Salary {
        public:
    
        private:
            Salary() : revenue_{}, cost_{} {}
            Salary(int x, int y) : revenue_{ x },
            cost_{ y } {
    
            }
            int revenue_, cost_;
            friend class Employee;
    };
    
    class Employee {
        public:
            std::string name_;
            Salary sal;
    };
    
    int main(){
    
        Employee emp{}; // "Salary::Salary()" is inaccessible
    }
    
  • The problem goes away if I forward declare main:

    int main(int, char*[]);
    

    And make main a friend of class Salary like so in Salary:

    class Salary {
        //...
        friend int main(int argc, char* argv[]);
    };
    

Now the program compiles correctly!

*** Another thing in main if I declare an object this way:

Employee emp; // ok
Employee emp{}; // error?
like image 978
Syfu_H Avatar asked Apr 23 '19 21:04

Syfu_H


People also ask

What happens when constructor is private?

A private constructor in Java is used in restricting object creation. It is a special instance constructor used in static member-only classes. If a constructor is declared as private, then its objects are only accessible from within the declared class. You cannot access its objects from outside the constructor class.

Can friend class call private methods?

Friend Class A friend class can access private and protected members of other class in which it is declared as friend. It is sometimes useful to allow a particular class to access private members of other class.

Is it allowed to define constructor in private section of the class?

Yes, we can declare a constructor as private. If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.

Can we create object of private constructor C++?

To create an object in C++, a constructor needs to be called. If the constructor that needs to be invoked is not accessible, then it can't be called, and the object cannot be created. The point of a private constructor is not preventing object construction.


1 Answers

Because you don't provide a constructor for Employee the braces in your initialization Employee emp{}; will perform an aggregate initialization, which essentially means that each member is initialized one-by-one using the default rules, in the context of main(). Since main() doesn't have access to the Salary constructor, it fails.

As others have pointed out, adding an Employee default constructor will resolve your problem:

class Employee {
    public:
        Employee() = default;
        std::string name_;
        Salary sal;
};
like image 161
zdan Avatar answered Oct 01 '22 01:10

zdan