scope

When can you have method in private part and data in public part of a class?
You should never have public data in an object.

But C++ isn't just used for object oriented programming so there are no general hard and fast rules about language constructs.
When a method or a data member is a part of a realization they shall be private. If a method or a data member is a part of an interface they shall be public.
For example in a class defined as Point there are usually two data members called x and y that are public. Another example is standard class std::pair. It has two data members, first and second, that are public. x and y in case of the class Point and first and second in case of the standard class std::pair are parts of open interfaces.
You should never have public data in an object.



Ehhhh...... I disagree.

Pointless getters/setters can be worse than public members. it depends entirely on the situation.

The classic example is a mathematical vector class:

1
2
3
4
5
6
7
8
class Vector
{
public:
  double x, y;  // <- there is no reason to make these private
  //  doing so would be absurd

  //... support functions and overloaded operators here
};
That's not an object. So the rule doesn't apply.
It's not encapsulated, but it's certainly an object.
You can only talk to an object by sending it a message.

In C++'s endevour to implement static type checking on objects, their methods and messages, objects are implemented by classes, methods are implemented as virtual member functions and sending messages as calling member functions.

There's nothing in that model about accessing data directly.

I wrote some spiel on this previously.
http://v2.cplusplus.com/forum/general/42423/#msg229336
There's nothing in that model about accessing data directly.


And yet people do, every day. Is this a "no true Scotsman" kind of deal?
Last edited on
kbw: How are you defining the term "object"? Because it sounds to be like you're defining an object as something that has no public members. In which case you're right... an object should never have public members because if it does, that (by definition) makes it not an object.

My definition is very simple. An object is an instance of a class. I find that's what most people mean when they say "object".

In this case, an instance of my example Vector class would be an object, but would have public members.


But really we're just arguing semantics at this point. I agree that for classes that are encapsulated you typically should not have public data members (though even then I wouldn't go so far as to say "always")
Last edited on
But really we're just arguing semantics at this point.
It's always contentious when someone says "Never do ...", so I guess I should expect to have to explain myself. But I really thought it was self evident.

kbw: How are you defining the term "object"? Because it sounds to be like you're defining an object as something that has no public members. In which case you're right... an object should never have public members because if it does, that (by definition) makes it not an object.
I probably meant object oriented class and certainly not C++ class. But object, being an instance of class, is a shortcut to what I meant. So, to reword it, neither the object classification or an instance of that classification should have public data. But that sounds awful and doesn't really answer the OPs question.

My definition is very simple. An object is an instance of a class. I find that's what most people mean when they say "object".
That's a tricky one. Do you mean most C++ people? C++ has a constrained object model and the keyword class implements a variety of concepts (interface, object, abstract data type, type, record).

In this case, an instance of my example Vector class would be an object, but would have public members.
In my thinking, a vector isn't an object. It's an abstract data type. The difference is that an abstract data type is just encapsulation, but objects can be specialised. BTW, I don't recall seeing public data on vector.

For example, in the C standard library, a file is represented by a FILE* data member and fopen, close, fread, fwrite, fseek, ftell, fprintf, fscanf and so on. That's an abstract data type. In C++, that could be implemented as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CFILE
{
    FILE* imp_;

publc:
    CFILE(const char* name, const char* mode)
    {
        imp_ = fopen(name, mode);
        if (!imp_)
        {
            throw std::runtime_error("fopen failed"); // something more elaborate
        }
    }
    ~CFILE() { fclose(imp_); }
    read(void* buf, size_t size) { fread(buf, size, 1, imp_) }
    // ... and so on 

I'm calling that an abstract data type and not a class. I don't think public data is fine, otherwise you can't treat it as a black box.

Here's another one,
1
2
3
4
5
6
7
8
9
class CRect
{
    int x, y, dx, dy;

public:
    CRect() { x = y = dx = dy = 0; }
    void origin(int top, int left) { x = top; y = left; }
    void width(int w) { dx = w; }
    // and so on 

I'm calling that a record. Public data is fine, it just a grouping of units.

How about this one:
1
2
3
4
5
class CWnd : public CObject
{
    HWND m_hWnd;
public:
    // ... and so on 

This is a class in the object oriented sense, and it should never have public data as it does in this example.
> When can you data in public part of a class?

a. When the data is immutable. For example:
1
2
3
4
5
6
7
8
9
10
11
12
struct person
{
    public:

        const std::string name ;
        const std::time_t date_of_birth ;

        // ...

    private:
        // ...
};


b. Where there is no invariant that can be identified for the member variable. Fo instance, std::pair<> or the example by Dish.

c. When the type is programatically not visible from outside the component in which it is defined.
1
2
3
4
5
6
7
8
9
namespace
{
     struct my_implementation_helper
     {
            // everything in this is public 
     } ;
}

// rest of implementation... 



> When can you have method member function in private part?

When it is an implementation detail, of interest only to the implementor of the class. For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct patricia_trie
{
    // ...

    private:

        struct node
        {
            // implementation detail not accessible outside; so everything is public
            std::string label ;
            std::vector< std::shared_ptr<node> > subtrees ;
            // ...
        } ;

        // ...

        // implementation detail:
        private:
            static std::pair<std::size_t,std::size_t> longest_substring_match(
                              const std::string& str, const std::shared_ptr<node> node ) ;
};


Topic archived. No new replies allowed.