Why I cannot instantiate a class whose constructor is private in a friend class? Announcing...

Why is water being consumed when my shutoff valve is closed?

Is there a possibility to generate a list dynamically in Latex?

What is the evidence that custom checks in Northern Ireland are going to result in violence?

My admission is revoked after accepting the admission offer

Has a Nobel Peace laureate ever been accused of war crimes?

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

Why isn't everyone flabbergasted about Bran's "gift"?

Does using the Inspiration rules for character defects encourage My Guy Syndrome?

Marquee sign letters

When does Bran Stark remember Jamie pushing him?

Does Prince Arnaud cause someone holding the Princess to lose?

What *exactly* is electrical current, voltage, and resistance?

Does a Draconic Bloodline sorcerer's doubled proficiency bonus for Charisma checks against dragons apply to all dragon types or only the chosen one?

Is there a verb for listening stealthily?

How to translate "red flag" into Spanish?

Raising a bilingual kid. When should we introduce the majority language?

What is /etc/mtab in Linux?

What does こした mean?

What's called a person who work as someone who puts products on shelves in stores?

Did war bonds have better investment alternatives during WWII?

What's the difference between using dependency injection with a container and using a service locator?

What helicopter has the most rotor blades?

Can gravitational waves pass through a black hole?

Is Bran literally the world's memory?



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



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30 pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Can an abstract class have a constructor?Why do this() and super() have to be the first statement in a constructor?Why can't I change a private member of a class from a friend class in a different namespace?Passing a class as argument which has a private constructor that takes no parametersPrivate data members are inaccessible to friend functionFriend function is not accessing private members of another friend classDeclaring constructors as private shows errors. Is at least one public constructor mandatory?Cannot access private member declared in class, even declared friend classPrivate Data member is inaccessible in Friend FunctionPassing an object into the constructor of another class





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







7















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 and only class Employee can instantiate it. So I declared the constructors of Salary private and made Employee 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 raised for me if I forward declare main:



    int main(int, char*[]);


    And make main friend of class Salary 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?









share|improve this question

























  • Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

    – J. Antonio Perez
    7 mins ago


















7















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 and only class Employee can instantiate it. So I declared the constructors of Salary private and made Employee 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 raised for me if I forward declare main:



    int main(int, char*[]);


    And make main friend of class Salary 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?









share|improve this question

























  • Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

    – J. Antonio Perez
    7 mins ago














7












7








7


6






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 and only class Employee can instantiate it. So I declared the constructors of Salary private and made Employee 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 raised for me if I forward declare main:



    int main(int, char*[]);


    And make main friend of class Salary 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?









share|improve this question
















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 and only class Employee can instantiate it. So I declared the constructors of Salary private and made Employee 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 raised for me if I forward declare main:



    int main(int, char*[]);


    And make main friend of class Salary 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?






c++ constructor friend-class






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 43 mins ago







Syfu_H

















asked 50 mins ago









Syfu_HSyfu_H

35518




35518













  • Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

    – J. Antonio Perez
    7 mins ago



















  • Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

    – J. Antonio Perez
    7 mins ago

















Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

– J. Antonio Perez
7 mins ago





Why are you making Salary's constructor private? It seems like there are contexts when you'd want to use Salary outside of Employee

– J. Antonio Perez
7 mins ago












4 Answers
4






active

oldest

votes


















7














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;
};





share|improve this answer





















  • 1





    I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

    – wally
    14 mins ago













  • GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

    – wally
    3 mins ago





















2














You have to explicitly declare the default constructor of class Employee thus you can initialize an abject via uniform initialization:



class Employee {
public:
Employee(){} // add it
std::string name_;
Salary sal;
};

int main(){
Employee emp{}; // now this should compile

}





share|improve this answer































    2














    You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.



    eg:



    class Employee {
    public:
    Employee() : sal() {}
    public:
    std::string name_;
    Salary sal;
    };





    share|improve this answer

































      0














      If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).






      share|improve this answer



















      • 1





        I recommend explaining why.

        – user4581301
        41 mins ago











      • Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

        – Syfu_H
        39 mins ago











      • @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

        – user4581301
        31 mins ago












      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55819962%2fwhy-i-cannot-instantiate-a-class-whose-constructor-is-private-in-a-friend-class%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      7














      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;
      };





      share|improve this answer





















      • 1





        I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

        – wally
        14 mins ago













      • GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

        – wally
        3 mins ago


















      7














      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;
      };





      share|improve this answer





















      • 1





        I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

        – wally
        14 mins ago













      • GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

        – wally
        3 mins ago
















      7












      7








      7







      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;
      };





      share|improve this answer















      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;
      };






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 16 mins ago

























      answered 31 mins ago









      zdanzdan

      22.1k34864




      22.1k34864








      • 1





        I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

        – wally
        14 mins ago













      • GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

        – wally
        3 mins ago
















      • 1





        I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

        – wally
        14 mins ago













      • GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

        – wally
        3 mins ago










      1




      1





      I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

      – wally
      14 mins ago







      I'm trying on MSVS and only Employee() {}; allows Employee emp{}; to compile. Clang seems to accept Employee() = default;, but then again, Clang seems to accept having no default constructor here.

      – wally
      14 mins ago















      GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

      – wally
      3 mins ago







      GCC does the same as Clang, and doesn't need a default constructor to compile in this case. Have you tried this answer on any specific compiler?

      – wally
      3 mins ago















      2














      You have to explicitly declare the default constructor of class Employee thus you can initialize an abject via uniform initialization:



      class Employee {
      public:
      Employee(){} // add it
      std::string name_;
      Salary sal;
      };

      int main(){
      Employee emp{}; // now this should compile

      }





      share|improve this answer




























        2














        You have to explicitly declare the default constructor of class Employee thus you can initialize an abject via uniform initialization:



        class Employee {
        public:
        Employee(){} // add it
        std::string name_;
        Salary sal;
        };

        int main(){
        Employee emp{}; // now this should compile

        }





        share|improve this answer


























          2












          2








          2







          You have to explicitly declare the default constructor of class Employee thus you can initialize an abject via uniform initialization:



          class Employee {
          public:
          Employee(){} // add it
          std::string name_;
          Salary sal;
          };

          int main(){
          Employee emp{}; // now this should compile

          }





          share|improve this answer













          You have to explicitly declare the default constructor of class Employee thus you can initialize an abject via uniform initialization:



          class Employee {
          public:
          Employee(){} // add it
          std::string name_;
          Salary sal;
          };

          int main(){
          Employee emp{}; // now this should compile

          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 33 mins ago









          Raindrop7Raindrop7

          3,74531224




          3,74531224























              2














              You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.



              eg:



              class Employee {
              public:
              Employee() : sal() {}
              public:
              std::string name_;
              Salary sal;
              };





              share|improve this answer






























                2














                You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.



                eg:



                class Employee {
                public:
                Employee() : sal() {}
                public:
                std::string name_;
                Salary sal;
                };





                share|improve this answer




























                  2












                  2








                  2







                  You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.



                  eg:



                  class Employee {
                  public:
                  Employee() : sal() {}
                  public:
                  std::string name_;
                  Salary sal;
                  };





                  share|improve this answer















                  You need Employee's ctor to call the ctor of Salary. The ctor of Salary is not accessible from main.



                  eg:



                  class Employee {
                  public:
                  Employee() : sal() {}
                  public:
                  std::string name_;
                  Salary sal;
                  };






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 22 mins ago









                  Pavan Manjunath

                  20.1k1181108




                  20.1k1181108










                  answered 43 mins ago









                  schuessschuess

                  536416




                  536416























                      0














                      If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).






                      share|improve this answer



















                      • 1





                        I recommend explaining why.

                        – user4581301
                        41 mins ago











                      • Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                        – Syfu_H
                        39 mins ago











                      • @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                        – user4581301
                        31 mins ago
















                      0














                      If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).






                      share|improve this answer



















                      • 1





                        I recommend explaining why.

                        – user4581301
                        41 mins ago











                      • Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                        – Syfu_H
                        39 mins ago











                      • @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                        – user4581301
                        31 mins ago














                      0












                      0








                      0







                      If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).






                      share|improve this answer













                      If you erase the "{}" after "Employee emp" in your main() function it compiles just fine (gcc 7.3.1 on Fedora 27).







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 43 mins ago









                      Eric SokolowskyEric Sokolowsky

                      514




                      514








                      • 1





                        I recommend explaining why.

                        – user4581301
                        41 mins ago











                      • Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                        – Syfu_H
                        39 mins ago











                      • @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                        – user4581301
                        31 mins ago














                      • 1





                        I recommend explaining why.

                        – user4581301
                        41 mins ago











                      • Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                        – Syfu_H
                        39 mins ago











                      • @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                        – user4581301
                        31 mins ago








                      1




                      1





                      I recommend explaining why.

                      – user4581301
                      41 mins ago





                      I recommend explaining why.

                      – user4581301
                      41 mins ago













                      Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                      – Syfu_H
                      39 mins ago





                      Yes. Not onyl GCC but also MSVC14 also compiles Employee emp; but why?

                      – Syfu_H
                      39 mins ago













                      @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                      – user4581301
                      31 mins ago





                      @Syfu_H Value Initialization. And I could be mistaken here (been caught on this in the past), but the Value Initialization is being replaced by Aggregate Initialization

                      – user4581301
                      31 mins ago


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55819962%2fwhy-i-cannot-instantiate-a-class-whose-constructor-is-private-in-a-friend-class%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      El tren de la libertad Índice Antecedentes "Porque yo decido" Desarrollo de la...

                      Castillo d'Acher Características Menú de navegación

                      Connecting two nodes from the same mother node horizontallyTikZ: What EXACTLY does the the |- notation for...