0

I want to access my Node struct in order to create a function that generates a new node. To do so i thought that the only way to do it is to create a constructor inside my struct and to call the constructor in my CreateNode function. However i get an error :[Error] 'struct BS::Node' is protected. An ovious sollution to the problem is to make struct Node public however i want to ask if there is another way to access my struct and keep it private.

Header file

class BS
{
public:
    BS();     //constructor
protected:
    struct Node{
        int data;
        Node* left;
        Node* right;
        Node(int d,Node* lf ,Node* ri)
            :data(d),left(lf),right(ri){}
    }; 
    Node* root;    
    Node* CreateNode(int data);
};

CPP

BS::BS(){
  root=NULL;
}  
BS::Node* CreateNode(int data){
    Node* new_node= new Node(0,NULL,NULL);
    return new_node;
}
brain_dead_cow
  • 83
  • 5
  • 13

2 Answers2

0

Use a public class with a private constructor, and make the outer class a friend:

class BS
{
public:
  BS();     //constructor

  class Node {
    // note: private constructor
    Node(int d,Node* lf ,Node* ri)
    :data(d),left(lf),right(ri){}

    int data;
    Node* left;
    Node* right;

    // befriends BS
    friend BS;
  }; 

  Node* CreateNode(int data);

private:
  Node* root = nullptr;
};

BS::Node* BS::CreateNode(int data){
    Node* new_node= new Node(0, nullptr, nullptr);
    return new_node;
}

int main()
{

}

ps. don't use raw pointers. Use std::unique_ptr

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • A nested class needs no friend specifier for the outer one –  Jun 14 '17 at 13:05
  • @StoryTeller the class in the OP worked perfect. Thre was no need to make all private and get access back with friend. –  Jun 14 '17 at 14:38
  • @manni66 - Your statement was made very general. You said *"A nested class needs no friend specifier for the outer one"*. You did not say *"There is no need for this transformation in the OP's code"*. The later is true, while the former is false. – StoryTeller - Unslander Monica Jun 14 '17 at 14:41
  • @StoryTeller agree, could have been more elaborate. –  Jun 14 '17 at 14:47
-2

No, you can not create your CreateNode function the way you would like, even with friendship, because this function returns a BS::Node outside BS, while Node is protected:

#include <BS.hh>

BS::BS()
{
  root=nullptr;
}

BS::Node* BS::CreateNode(int data)
{
    BS::Node* new_node = new BS::Node(0,nullptr,nullptr);
    return new_node;
}

int main()
{
  BS bs;
  BS::Node* = bs.CreateNode(1); // <- Error, returning a BS::Node outside BS!
  return 0;
}

But you could use CreateNode inside BS with:

class BS
{
public:
    BS();     //constructor
protected:
    struct Node{
        int data;
        Node* left;
        Node* right;
        Node(int d,Node* lf ,Node* ri)
            :data(d),left(lf),right(ri){}
    };
    BS::Node* CreateNode(int data);
    BS::Node* root = CreateNode(0); // inside BS it's OK
};
Ðаn
  • 10,934
  • 11
  • 59
  • 95
gaFF
  • 747
  • 3
  • 11