Today, I was curious to find some of differences between a structure and a class, in C++. So, I found some of the differences:
In a structure, by default members are public while private in class.
Inheritance in case of a structure is public by default, while private in case of class.
Classes can take part in templates, while structures cannot.
click here to see that a struct cannot be used in place of class in case of template.
http://ideone.com/p5G57
template<struct T> void fun(T i)
{
cout<<i<<endl;
}
int main()
{
int i=10;
fun<int>(i);
return 0;
}
It gives the errors:
prog.cpp:4: error: ‘struct T’ is not a valid type for a template constant parameter
prog.cpp: In function ‘void fun(T)’:
prog.cpp:4: error: ‘i’ has incomplete type
prog.cpp:4: error: forward declaration of ‘struct T’
prog.cpp: In function ‘int main()’:
prog.cpp:12: error: no matching function for call to ‘fun(int&)’
However, if struct is replaced with class, it works perfectly. see here: http://ideone.com/K8bFn
Apart from these above differences, when I replace class with struct in my code, the code works perfectly without making any further changes.
Now, I want to know, are there more differences, that I am missing and I should know?
There's no other difference, but the third one you specify isn't correct:
Class can take part in template while structures cannot.
In case of templates, the class keyword is just syntactic sugar, it doesn't mean the type has to be an actual class. Generally, programmers prefer typename for basic types and class for classes or structs, but that's just by convention.
Other than that, you can use both class and struct to specialize templates.
There are two main differences:
In absence of an access-specifier for a base class, public is assumed when the derived class is declared struct and private is assumed when the class is declared class.
Member of a class defined with the keyword class are private by default. Members of a class defined with the keywords struct or union are public by default.
A struct is just a class with all members public by default.
According to The C++ Programming Language (3rd ed.), section 10.2.8:
By definition, a struct is a class in which members are by default
public; that is
struct s{ ...
is simply shorthand for
class s { public: ...
Then he goes on to say:
I usually prefer to use struct for classes that have all data public.
I think of such classes as "not quite proper types, just data
structures."
Edited per the comments:
In section 15.3.2 it says:
The access specifier for a base class can be left out. In that case,
the base defaults to a private base for a class and a public base
for a struct.
Related
I have a class that looks something like this:
class A
{
public:
void foo(int arg) { foo(arg, false); }
private:
void foo(int arg, bool flag) {}
};
It is built this way because I want foo's flag argument to only be false when called from outside A. I want to inherit it privately, but allow calling foo:
class B : private A
{
public:
using A::foo;
};
However, this fails because the using declaraion attempts to bring all the overloads of foo into scope, including the private one, which the the compiler rightly rejects.
This isn't hard to fix, I can either:
Change the accessibility of A::foo(int, bool) to protected or public
Inherit A publicly; only public overloads of foo will be inherited
Change the name of A::foo(int, bool) so that the using declaration does not attempt to bring it into scope
This is a small, private project, and besides, that overload is only called inside A. So fixing the problem is a non-issue here. (I'm just going to rename the private overload.)
But it doesn't feel like it should be necessary. Why does the using declaration attempt to bring the non-accessible methods into scope? Is this particular case just not covered by the standard? Is there a way to fix this besides the methods I listed?
You can also redefine the overload you want and have it forward its argument to the function in A:
class B : private A
{
public:
void foo(int arg) { A::foo(arg); }
};
The using declaration is just too blunt a tool in this case. It brings function names into the derived class scope. And when the name refers to something private, it chokes. It can't distinguish overloads. The standard requires the names introduced by a using declaration to be accessible:
[namespace.udecl]/17
In a using-declarator that does not name a constructor, all members of
the set of introduced declarations shall be accessible. In a
using-declarator that names a constructor, no access check is
performed. In particular, if a derived class uses a using-declarator
to access a member of a base class, the member name shall be
accessible. If the name is that of an overloaded member function, then
all functions named shall be accessible. The base class members
mentioned by a using-declarator shall be visible in the scope of at
least one of the direct base classes of the class where the
using-declarator is specified.
The forwarding function can also be templated. So one won't need to redefine each function they want to expose individually.
class B : private A
{
public:
template<typename ...Args>
void foo(Args ...args) { A::foo(args...); }
};
It's "catch-all" like the using declaration, except the access specifier is checked only on template instantiation, i.e. when the function is called. So the template will be ill-formed based on its scope and whether or not the member in A is accessible there.
I found the following extract from Scott Meyer's Effective C++ which is related to your predicament (with emphasis added):
Item 33: Avoid hiding inherited names.
...
This means that if you inherit from a base class with overloaded functions
and you want to redefine or override only some of them, you need
to include a using declaration for each name you’d otherwise be hiding.
If you don’t, some of the names you’d like to inherit will be hidden.
...
It’s conceivable that you sometimes won’t want to inherit all the functions
from your base classes. Under public inheritance, this should
never be the case, because, again, it violates public inheritance’s is-a
relationship between base and derived classes. (That’s why the using
declarations above are in the public part of the derived class: names
that are public in a base class should also be public in a publicly
derived class.)
Under private inheritance, however, it can
make sense. For example, suppose Derived privately inherits from
Base, and the only version of the function that Derived wants to inherit is the
one taking no parameters. A using declaration won’t do the trick here,
because a using declaration makes all inherited functions with a given
name visible in the derived class.
No, this is a case for a different technique, namely, a simple forwarding function:
class Base {
public:
virtual void mf1() = 0;
virtual void mf1(int);
... // as before
};
class Derived: private Base {
public:
virtual void mf1() // forwarding function; implicitly
{
Base::mf1(); } // inline
};
}
I have a pure virtual template base class, in which I define a method get_value which takes an enumeration and returns an int. The complication is that each derived class will use a different enumeration. This isn't a problem if I just define the enumerations beforehand and pass them as template parameters to the base, however, since the enum type is directly related to the derived type, I want the enum to be defined within the derived class.
I was hoping to solve this by having the base class take the derived class as a parameter and then access the derived class's enum, like this:
template <typename child_type>
class base_type{
public:
int get_value(typename child_type::enum_type);
};
class child : public base_type<child>{
public:
enum enum_type{a,b,c};
};
MinGW reports
test.cpp: In instantiation of 'class base_type<child>':
test.cpp:7:22: required from here
test.cpp:4:6: error: invalid use of incomplete type 'class child'
int get_value(typename child_type::enum_type index);
^~~~~~~~~
test.cpp:7:7: note: forward declaration of 'class child'
class child : public base_type<child>{
^~~~~
I understand the errors; I just feel like there should be a way to do what I want to do and can't wrap my head around how to do it without getting too complicated. Is this possible, or am I going about it in the wrong way?
As for the specifics of my problem: the classes parse a record file which can be encoded in one of a few different encoding versions - the processing is mostly the same between versions and the bulk can be done in a non-virtual base function, with a call to a virtual function to do version-specific things. Different versions also extract slightly different value names, which I am trying to capture in the version-specific enums. The position of each named value inside the record will be stored in the value of the corresponding enum member value.
There's probably a better way to go about it but I haven't been able to think of it. I suppose in this case I could just have get_value take an int in the base class, use the child class enums to make the call, and just let the cast happen, but I was hoping to see if the more general case of a base class using a type defined in a child was possible.
The best solution I can think of is using child traits.
template <typename child_type>
class base_type{
public:
int get_value(typename child_type::enum_type);
};
struct child_traits {
enum enum_type{a,b,c};
};
class child :
public child_traits,
public base_type<child_traits>{
};
I am making a project, which requires multiple classes, some of them are inherited!!
So i am using one inherited class in a main class before it's definition!
Kindly help me to how to use prototype declaration for inherited class.thanks!!
Example:
class A
{
/*data*/
};
class B:public A
{public:
void func()
{
C obj;
}
};
class C:public B
{
};`
Only functions have prototypes. What you can do with class is to forward declare it.
class MyFutureClass;
struct MyFutureStruct;
These is an incomplete classes. No, that structs in C++ are same as classes, just they have public access by default, classes have private. To make them complete you should provide definition anywhere further in code.
Incomplete class is just one possible incomplete type. The following types are incomplete types:
type void;
class type that has been declared but not defined;
array of unknown size;
array of elements of incomplete type;
enumeration type until its underlying type is determined.
Now what you can use incomplete class for?
declare a pointer variable or class field
Declare a function or method that accepts argument or returns of incomplete type, without defining it.
what you can't do with it?
Inherit incomplete class by other class
Define objects fields of incomplete type
Declare non-static class data member of incomplete type
Use incomplete class type as parameter for template
Define functions that use argument of incomplete type or
Perform implicit or explicit conversion to incomplete class, implicit or explicit, lvalue-to-rvalue conversions, standard conversion, dynamic_cast, or static_cast to pointer or reference of incomplete type, except when converting from the null pointer constant or from a pointer to void (void* always can be converted and void never is defined)
Access incomplete class' members or methods
Use new expressions that create object of incomplete type
Use it in catch-clause
Use typeid, sizeof, or alignof operator
Use arithmetic operator on pointer to incomplete class (because sizof isn't known , of course)
What it is needed for?
To avoid cyclic dependency of headers, when one class depends on existence and functionality of other
To reduce amount of headers included in single file. You can define class that got pointers and formal parameters of declared class without defining it
let's see, this is an absolutely useless example of avoid cyclic use of headers.
[class_a.h]
class B;
class A
{
B* p;
public:
A ( B& value );
};
[class_b.h]
#include "class_a.h"
class B : public A // we need complete A to inherit it
{
int a;
public:
B ( const B& );
};
[class_a.cpp]
#include "class_b.h"
// to define this constructor we need complete A, but header with complete
// definition is already included within class_b.h header
A::A ( B& val) : p( new B(val)) // we created copy of B
{
}
So, to define class A we need class B, but class B is child of class A, thus it needs complete definition of A. Conundrum? No. Thanks to forward declaration, we can define class A without defining B.
(PS. If someone reviewed code and found something impossible there, my explicit allowance to fix it is due... I'm falling asleep)
Unfortunately, I studied class design and design patterns mostly in the context of Java; thus, I sometimes have a hard time to translate a familiar pattern to C++.
Assume we want to have a base class which's functionality is extended by a sub-class. In Java, we would do something like this:
public class BaseClass<T> {
//T is used here
protected int foo = 0;
}
public class DerivedClass<T> extends BaseClass<T> {
public void incr_foo() {
++foo;
}
}
Which I directly translated to C++:
template<class T>
class BaseClass {
protected:
size_t foo = 0;
//T is used here
};
template<class T>
class DerivedClass : public BaseClass<T> {
public:
void incr_foo() {
++(this->foo);
}
};
Since the C++ semantics of 'protected' diver from the Java-semantics, we need to use something like 'this->foo' to access protected members of the base class.
Edit: If we just use '++foo', the compiler gives the error: 'use of undeclared identifier foo'.
EditEnd
If you need to access several members of the base class, this can get a bit tedious and is not so nice to read.
Is this a good design desicion? If not, what better ways are there to achieve this?
This has nothing to do with the member being protected; you'd get the exact same error with a public member.
The real reason is that templates are involed. More specifically, that your class template has a base class which depends on a template parameter. This means that when parsing the template, the compiler will not (be able to) look into that base class to find inherited members which are used unqualified. It makes sense: when the template is parsed, the template parameter values are not known yet and thus the compiler has no idea what members the base class will have (remember partial and total specialisation exist!).
In order to overcome this, you must somehow tell the compiler that the name foo depends on template parameters (that it's a dependent name). Once you do so, the compiler will not try to resolve it when parsing the template; it will postpone resolution until the template is instantiated. At that point, template arguments are known and thus the base class can be checked.
You have three ways to mark a member name as dependent:
Refer to the name through this, as you're doing: this->foo
Refer to the name through base-class qualification: BaseClass<T>::foo
Bring the name into the scope of the derived class:
template<class T>
class DerivedClass : public BaseClass<T> {
protected:
using BaseClass<T>::foo; // from this point on, `foo` is a dependent name
public:
void incr_foo() {
++foo; // works fine now
}
};
BaseClass<T> is a dependent type - it depends on the template parameter used to instantiate DerivedClass. Until DerivedClass instantiated, the compiler doesn't know what the type is: it might be an instantiation of the generic template, or it might be an explicit specialisation, with different members.
So, within the definition of DerivedClass, there is no way to know which names refer to members of the base class. You have to specify that they are, using this-> or BaseClass::.
In a class with a non-dependent base class, you can use any accessible base-class members as if they were direct members, just as in Java.
I recently ran into a problem when using a private inheritance scheme in which the base class defined a template method and the (privately) derived class made that method public via a using declaration under the public access specifier. The template was designed to take the address of a function and invoke that function pointer. However, upon attempting to pass the name of the function to the derived class template method, I receive an error message that states that the base-class method cannot access a private member declared in the derived class. Here is a code segment that models the issue:
class A
{
public:
template<class T> void Funct(T pFunct) { }
};
class B : private A
{
public:
using A::Funct;
};
void Show(void) { }
int main(void)
{
B b;
b.Funct(Show);
}
The exact resulting error message is: 'A::Funct' : cannot access private member declared in class 'B'
I am able to resolve the issue simply by:
1)Preceding the function argument name with the address-of operator:
b.Funct(&Show);
2)Explicitly qualifying the template type argument:
b.Funct<void(*)(void)>(Show)
If the Show() function were a template as well, I would need to explicitly qualify the template using the proper template type arguments used to instantiate Show.
My question is not how to solve the problem but why the error message is being generated. Why does instantiating Funct() with Show versus with &Show cause the compiler to do two different things. And why does instantiating Funct() with Show cause the Funct() method to attempt to access the private data in class B (which I'm assuming is the A subobject in class B)?
Compiles fine with Comeau Online. Ergo, compiler bug. Report it.
Cheers & hth.,
bcc32 gives error: error bccE2247: 'Funct<void (*)()>(void (*)())' is not accessible in function main()
I believe this is a compiler bug.