I've some little question about STL iterator implementation.
why iterator defining as a struct but not as class?
what is the main reason?
It is an implementation choice. class and struct are almost the same in C++, the difference being the default access specifiers and inheritance, which are private for class and public for struct. So if a type has little need for private data members it may make more sense to implement it as a struct. But you can have exactly the same type implemented as either:
struct Iterator : IteratorBase {
SomeType x;
};
is exactly the same as
class Iterator : public IteratorBase{
public:
SomeType x;
};
This is defined in the standard, 24.2 which describes the <iterator> header, which are struct. This choice was probably made because iterators provide access to container elements and making them class would be useless, the only difference being that class has private access level by default, whereas struct has public access level.
So there were 2 choices if declaring iterators class instead of struct:
make all members public, which is useless since the same effect can be obtained by making it directly struct.
make getters, which would provide unnecessary overhead and abstraction.
Who says you that iterator is defined by struct? In standart there is nothing about it. Struct and class have only one difference - access to the elements as default. So, in struct by default access is public and in class by default access is private.
Like the best answer
class and struct is the same except the access.so use struct or class don't have many difference.
we know the C++ is include C
using struct seem simply and making a distinction between struct and class.
this is the define of iterator
struct output_iterator_tag{}
struct input_iterator_tag{}
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag{}
struct random_accessl_iterator_tag : public bidirectional_iterator_tag{}
Related
I am using private inheritance to model my has-a relationship, but my base class type is rather complicated (well, a little bit), and I would like to have a typedef for it. Is something like the following possible in C++
struct S : private typedef std::vector<int> Container {};
Currently I am doing:
template< typename Container = std::vector<int> >
struct S : private Container {};
But this
makes my class to a template class. This is not a big problem for my current application (since it is a template class anyway), but in general is not nice.
could lead to bugs, when people think they are allowed to specify their own container.
Considering that:
Inheriting from standard containers is not advisable;
Composition can replace private inheritance in most cases;
You want to control the container that will be used;
you could prefer private composition:
struct S {
using Container = std::vector<int>; // outside struct also possible
private: Container container;
};
There is no code duplication here: with inheritance, you'd just have a container sub-object whereas with composition you'd have a container member, and both would use the same code.
There is no decisive advantage of private inheritance, since other classes could not use the public members defined in the base class. The only advantage is that you can use public members in the class definition, whereas with composition, you'll have to prefix the member with the object name.
For example, I have a class subclassing a vector
class A : private vector<int>
{
};
This make all methods in vector private in class A. I'd like to make the const methods in vector, like size(), public; and non-const methods, like push_back(), private. How to implement it?
You can use a using-declaration to (re)introduce the names of inherited functions, placing them in a public "section" will make all function overloads in the referred class with that name publicly accessible:
#include <vector>
#include <iostream>
class A : private std::vector<int>
{
public:
using vector::size;
A(vector p)
: vector(std::move(p))
{}
};
int main()
{
A a({1,2,3,4});
std::cout << a.size();
}
Note: I'm using vector, the injected-class-name of vector<int>, which is inherited to A. It is not necessary to explicitly type the template arguments.
The accepted answer of the related question "How to publicly inherit from a base class but make some of public methods from the base class private in the derived class?" shows the same technique. That should be a hint to search for an answer first ;) Note, however, that answer uses access-declarations, which have been deprecated in C++03 and I can find no sign of them in C++11 (i.e. don't use them, prefer a using-declaration as shown here).
Instead of using direct inheritance, encapsulate using the bridge pattern.
bridge pattern
You can just create a typedef to a const vector: typedef const std::vector<int> A;
This allows user to declare objects like A val; and will disable access to non-const methods. (calling them will cause compile-time error)
The disadvantage is that they aren't different types, so you can pass objects of type A to functions that expect const std::vector<int>. If having two separate types is what you require, then you have to wrap every method manually with delegation (C++ should have had strong typedefs already :-( )
I have read that the main differences between classes and structures (other than functions), is that class members default to private, whereas structure members default to public.
That implies that structure members can be private. My question is: Can you have private structure members? And if you can, what is the purpose of using private members? How would you even access them?
Yes structures can have private members, you just need to use the access specifier for the same.
struct Mystruct
{
private:
m_data;
};
Only difference between structure and class are:
access specifier defaults to private for class and public for struct
inheritance defaults to private for class and public for struct
How can you access them?
Just like you access private members of a class. i.e: they can only be accessed within the structures member functions and not in derived structure etc.
The only difference between struct and class is default access (with the exception of some weird template situations, see Alf's comments below). This means you can access private members in the same way as in a class:
struct foo {
int get_X() { return x; }
void set_X(int x_) { x = x_; }
private:
int x;
};
Whether you use struct or class, then, is purely a matter of style. I tend to use struct when all members are public (eg, if it's a functor class with no member variables and only public functions).
One thing that makes this useful is that you can also use the friend key word in structs, so private members can only be used and modified by those specific functions or classes or what not that you want to be able to modify it. This way the user can't modify those sections themselves. They won't even show up in the auto fill features, at least in visual studio.
Can we describe functions in a struct? For example, is this code valid?
struct function {
int func() { return 5; }
};
Yes, the only differences between a struct and class in C++ are:
In C++, a structure is a class defined with the struct keyword. Its members and base classes are public by default. A class defined with the class keyword has private members and base classes by default. This is the only difference between structs and classes in C++.
Yes. There is no functional difference between a class and a struct, and anything you can do with one (such as defining a member function), you can do with the other.
If you're interested, the only difference is that members and base classes are private by default in a class, and public by default in a struct.
Yes, you can, the difference to class is the access limitations to its members and methods. The struct has all its members and methods public by default.
Yes, it is totally part of the standard.
A struct is a class with all its members public by default.
The question says it all really. Am I allowed derive a class from a struct, or should I create a class that embeds my struct and defines copy constructors and an = operator to move between the two?
In C++ struct is (almost) synonymous to a class (except of different default access level), so yes, you can.
struct A {
// fields are public by default
};
class B: public A {
// fields are private by default
};
I'm not familiar with MFC, but it looks like an attempt to maintain both C and C++ APIs.
Of course you are. What is different regarding the inheritance is that if you define a class, it will inherit private from other classes/structs. If you define a struct and derive it from a class or struct, it will be a public inheritance by default:
// the following two are equivalent except that one time class is
// used and the other time struct
struct f : g { };
class f : public g { };
If you wonder how you should wrap C structs - i would embed them as a member into the class. Because the C structs were not designed to be inherited from (think of the neither protected nor virtual destructor in the C structs - they can't have one). They are simple aggregates that collect data. And putting them as members uses them as such (as in "a point has a pair of an x and an y coordinate").
C structs also expose members that possibly should not be exposed in the class. Containment allows precise control over what is exposed and what not by get/set functions and you can still let it give you a copy or reference to the contained naked C struct object.
Yes. you can derive a class from a struct. In C++, a struct is simply a class where the default access is public rather than private. Deriving a class from a struct that only adds non-virual member functions and/or static functions is a useful technique to provide a C++ interface while maintaining compatability with a C style API.
This is exactly the approach used by MFC for many of the C structs (contrary to what you state in your question).
For example, the CRect class is publicly derived from struct tagRECT (the more commonly used name RECT is a typededf for struct tagRECT). Because struct tagRECT defines all the data members, and CRect adds only non-virtual member functions, the memory layout of CRects and RECTs are identical - you can use a CRect as an argument for any function expected a RECT and vice-versa.