Why can I use double colons in functions and classes not defined but I can't use in variables ??
Example:
#include <iostream>
using namespace std;
class Person{
public:
int age;
string name();
};
int Person::age = 10; //It outputs an error
string Person::name(){ //It doesn't
return "n";
}
Why can I use double colons in functions and classes not defined but I can't use in variables ??
age is an instance field, it exists in multiple places in memory - one for each Person that exists.
I'll now expand in detail about what the :: operator does, how to use it, and how static class members compare to instance members:
The :: operator:
The :: (the scope-resolution operator) has multiple uses in C++:
If you're familiar with Java, C# or JavaScript then it can be likened to the dot dereference or "navigation operator" . (e.g. namespace.Class.Method().Result) - except C++ uses a different operators for different kinds of navigation and dereferencing:
. is the member-access operator, similar to C - it's only applicable for "object values" and references (foo&), not pointers (foo*).
-> is another member-access operator for pointer types, note that this operator can be overridden but . cannot (overridin -> is risky but it improves the ergonomics of smart-pointer libraries when done correctly).
:: is the scope-resolution operator - it has a few different uses:
Namespace navigation - whereas Java and C# use . to navigate packages and namespaces, C++ uses ::, for example: using std::time.
When unqualified, it's also used to reference the global namespace, e.g. ::std which is handy if you're writing code which is already in a namespace.
It's also used to access static members of types - typically an actual static member (a static method or field) but also items like enum class (scoped enumeration) values (e.g. SomeEnumClass::value_name)
Finally, it's also used to select a specific base method when dealing with virtual method implementations: it's used when an overridden method needs to call a base implementation in a superclass - C++ does not have the singular base or super keywords that C# and Java have (respectively) because C++ allows multiple inheritance, so you must specify the specific parent class name: How to call a parent class function from derived class function?
Anyway, in your case, it looks like you're confused about what instance and static members actually mean, so here is an illustration:
class Person {
public:
int height; // each Person has their own height, so this is an instance member
static int averageHeight; // but an individual Person doesn't have an "average height" - but a single average-height value can be used for all Persons, so this is a shared ("static") value.
int getAverageHeight() { // this is an instance method, btw
return Person::averageHeight; // use `Person::` to unambiguously reference a static member of `Person`
}
Person()
: height(0) {
// instance members should be initialized in the constructor!
}
}
// This will create an array of 10 people (10 different object instances).
// Each Person object (an instance) will have its own `height` in memory
Person* multiplePeople = new Person[10];
// btw, you probably should use `std::array` with an initializer instead:
// array<Person,10> multiplePeople{}; // <-- like this
// This sets a value to the `staticField` member, which exists only once in memory, that is, all Person instances share the same value for this member...
Person::averageHeight = 175; // 175cm
// ...for example:
assert( 175 == multiplePeople[3]->getAverageHeight() );
assert( 175 == multiplePeople[6]->getAverageHeight() );
// However instance members can have different values for each instance:
multiplePeople[3]->height = 170;
multiplePeople[6]->height = 180;
// Btw `height` is initialized to 0 in each Person's constructor.
assert( 170 != multiplePeople[0]->height );
assert( 180 != multiplePeople[7]->height );
Related
I have an abstract class that looks something like
class Protocol
{
public:
// format the string to json or xml depending on impl
virtual std::string& format(Message& msg) = 0;
// parse the message from json or xml depending on impl
virtual Message& parse(std::string& str) = 0;
}
for formatting parsing a structure Message from/to a std::string
struct Message
{
unsigned long id;
unsigned char command;
unsigned int value;
/* some more fields */
}
Now I have another class `` that relies on that class by having a member of that type. Of course this member is expected to be of a subtype of Calculator
// client.h
class Client
{
public:
Client(Protocol& protocol);
/* some methods, e.g. */
void request(unsigned int amout);
private:
/* this is what the question below refers to */
Protocol* pProtocol; // will compile
Protocol cProtocol; // won't compile (see below)
Protocol& rProtocol; // what does this mean?
}
// client.cpp
Client::Client(Protocol& protocol) :
// depending on the member
pProtocol(&protocol) // or
cProtocol(protocol) // or
rProtocol(protocol)
{
}
void Client::request(unsigned int amount)
{
Message msg;
msg.id = 1234;
msg.command = 100;
msg.value = amount;
std::string str =
// depending on the member
pProtocol->format(msg); // or
cProtocol.format(msg); // or
rProtocol.format(msg);
// some more code to send the string to the server
}
So here are my questions:
I know I should prefer members of class type like cProtocol since pointers like pProtocol may be NULL
unfortunately this won't compile with the message
cannot declare field 'Client::cProtocol' to be of abstract type 'Protocol'
which I understand, since the abstract class Protocol cannot be instantiated.
So what should I prefer? A reference member or a pointer member?
What are the differences between the 3 options? Especially between cProtocoland rProtocol (except .vs. -> and the fact that the pointer may be NULL)
What if I don't initialize rProtocol in the constructor? Will this compile? What would it contain? Since it cannot be instantiated with a default value!?
I know I should prefer members of class type like cProtocol since pointers like pProtocol may be NULL
Generally, you prefer objects to pointers, because the language helps you manage resources by calling destructors on them. However, you can achieve the same effect with smart pointers, such as std::shared_ptr<T> or std::unique_ptr<T>.
unfortunately this won't compile with the message "cannot declare field Client::cProtocol to be of abstract type Protocol" which I understand, since the abstract class Protocol cannot be instantiated.
This is not the right reason: it is done because of object slicing, because slicing your objects down to an abstract type is not allowed.
So what should I prefer? A reference member or a pointer member?
In order to use a reference, three conditions are necessary:
The referenced object must be available in the constructor
The presence of the referenced object is mandatory (because you cannot set a reference to NULL), and
You do not need to re-point the referenced object to some other object, or "clear out" the reference at some later time.
If these three conditions are met, you can use a reference. This tells the readers of your code that your class instance has strong bounds to the referenced instance, because of the three conditions above.
What are the differences between the 3 options? Especially between cProtocoland rProtocol (except . vs. -> and the fact that the pointer may be NULL)
cProtocoland makes a copy (if it weren't abstract, it would) and slices off all the derived functionality. rProtocol uses some other object, and keeps it polymorphic. pProtocol gives you more flexibility on when to assign or re-assign it, and on assigning NULLs. In exchange for that you need to NULL-check the pointer, and optionally manage resources associated with it in copy constructors, assignment operators, and so on.
What if I don't initialize rProtocol in the constructor? Will this compile? What would it contain? Since it cannot be instantiated with a default value!?
If you cannot initialize a reference in the constructor, you cannot use a reference for that member at all: a pointer becomes your only choice.
I have seen code like this, so I'm trying to find the reason.
What's the main reason for having static functions that act as constructors, instead of having actual constructors?
I mean something like:
class MyClass
{
public:
static MyClass CreateFrom( bar );
static MyClass CreateFrom( foo );
...
}
instead of:
class MyClass
{
public:
MyClass( bar );
MyClass( foo );
...
}
This is called the "named constructor idiom".
It's typically used when:
You have a lot of ctors with similar enough enough parameter lists that overloaded ctors would be confusing (e.g., different mixtures of integer and floating point numbers, so 1, 1.0, 1 is supposed to mean something different from 1, 1, 1.0).
You have two different sources that both provide the input as the same type. For example, let's assume you wanted to convert a distance on the surface of the earth into the angle subtended between points that distance apart -- but you might want to supply the distance in either miles or kilometers, either of which would be represented as a double.
In this case a single angle(double dist) can't distinguish between input in kilometer vs. miles, but: angle_from_miles and angle_from_kilomters can do that quite easily.
They are called Named Constructors.
The are basically used when you want to construct an object which requires to pass a particular set of parameters but internally you need to construct the object differently.
For example you have a class like:
class AREA
{
double area;
AREA(int x);
};
//how will you construct the object differently in case of circle and square??
For this purpose, we have named constructors which help to create a relevant object.
So we may create 2 static methods inside the class as:
static AREA square(int x)
{ return AREA(x*x); }
and
static AREA circle(int x)
{ return AREA(x*x*3.14); } //or a more accurate PI value
Thus, we may call the relevant static function to return the object initialized with the required area.
NOTE: These are static as while creating an object for a particular class you shouldn't be requiring an object to do so.
Check THIS for more details.
The most obvious benefits are:
It's easy to specify the implementation which constructs the instance at the callsite, when multiple constructors are provided. This makes it easier for the class to provide multiple variants.
These variants may also have different names, but identical parameter lists (or parameter lists which the compiler may call out as ambiguous when determining which to choose).
It helps you because you can read which constructor your implementation calls -- at the callsite.
Another reason is that it is easier in some cases to initialize the class within a function body, rather than using an initialization list.
This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 4 months ago.
I created a class called Kwadrat. The class has three int fields. My Development Environment suggests that I access the fields from Kwadrat created objects via the :: & -> operators. I tried both operators, and found that the -> operator is able to successfully access the data in the objects fields, although, the same cannot be said for the -> operator.
I have also found that the . operator will access class members as well. I am confused, and don't understand why there are three members for accessing object members &/or methods. Can someone please explain to me what the difference is between the three operators?
1. ->
2. ::
3. .
#include <iostream>
using namespace std;
class Kwadrat{
public:
int val1,
val2,
val3;
Kwadrat(int val1, int val2, int val3)
{
this->val1 = val1; // Working
this.val2 = val2; // Doesn't Work!
this::val3 = val3; // Doesn't Work!
}
};
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
1.-> for accessing object member variables and methods via pointer to object
Foo *foo = new Foo();
foo->member_var = 10;
foo->member_func();
2.. for accessing object member variables and methods via object instance
Foo foo;
foo.member_var = 10;
foo.member_func();
3.:: for accessing static variables and methods of a class/struct or namespace. It can also be used to access variables and functions from another scope (actually class, struct, namespace are scopes in that case)
int some_val = Foo::static_var;
Foo::static_method();
int max_int = std::numeric_limits<int>::max();
In C++ you can access fields or methods, using different operators, depending on it's type:
ClassName::FieldName : class public static field and methods
ClassInstance.FieldName : accessing a public field (or method) through class reference
ClassPointer->FieldName : accessing a public field (or method) dereferencing a class pointer
Note that :: should be used with a class name rather than a class instance, since static fields or methods are common to all instances of a class.
class AClass{
public:
static int static_field;
int instance_field;
static void static_method();
void method();
};
then you access this way:
AClass instance;
AClass *pointer = new AClass();
instance.instance_field; //access instance_field through a reference to AClass
instance.method();
pointer->instance_field; //access instance_field through a pointer to AClass
pointer->method();
AClass::static_field;
AClass::static_method();
Put very simple :: is the scoping operator, . is the access operator (I forget what the actual name is?), and -> is the dereference arrow.
:: - Scopes a function. That is, it lets the compiler know what class the function lives in and, thus, how to call it. If you are using this operator to call a function, the function is a static function.
. - This allows access to a member function on an already created object. For instance, Foo x; x.bar() calls the method bar() on instantiated object x which has type Foo. You can also use this to access public class variables.
-> - Essentially the same thing as . except this works on pointer types. In essence it dereferences the pointer, than calls .. Using this is equivalent to (*ptr).method()
You have a pointer to an object. Therefore, you need to access a field of an object that's pointed to by the pointer. To dereference the pointer you use *, and to access a field, you use ., so you can use:
cout << (*kwadrat).val1;
Note that the parentheses are necessary. This operation is common enough that long ago (when C was young) they decided to create a "shorthand" method of doing it:
cout << kwadrat->val1;
These are defined to be identical. As you can see, the -> basically just combines a * and a . into a single operation. If you were dealing directly with an object or a reference to an object, you'd be able to use the . without dereferencing a pointer first:
Kwadrat kwadrat2(2,3,4);
cout << kwadrat2.val1;
The :: is the scope resolution operator. It is used when you only need to qualify the name, but you're not dealing with an individual object at all. This would be primarily to access a static data member:
struct something {
static int x; // this only declares `something::x`. Often found in a header
};
int something::x; // this defines `something::x`. Usually in .cpp/.cc/.C file.
In this case, since x is static, it's not associated with any particular instance of something. In fact, it will exist even if no instance of that type of object has been created. In this case, we can access it with the scope resolution operator:
something::x = 10;
std::cout << something::x;
Note, however, that it's also permitted to access a static member as if it was a member of a particular object:
something s;
s.x = 1;
At least if memory serves, early in the history of C++ this wasn't allowed, but the meaning is unambiguous, so they decided to allow it.
The three operators have related but different meanings, despite the misleading note from the IDE.
The :: operator is known as the scope resolution operator, and it is used to get from a namespace or class to one of its members.
The . and -> operators are for accessing an object instance's members, and only comes into play after creating an object instance. You use . if you have an actual object (or a reference to the object, declared with & in the declared type), and you use -> if you have a pointer to an object (declared with * in the declared type).
The this object is always a pointer to the current instance, hence why the -> operator is the only one that works.
Examples:
// In a header file
namespace Namespace {
class Class {
private:
int x;
public:
Class() : x(4) {}
void incrementX();
};
}
// In an implementation file
namespace Namespace {
void Class::incrementX() { // Using scope resolution to get to the class member when we aren't using an instance
++(this->x); // this is a pointer, so using ->. Equivalent to ++((*this).x)
}
}
// In a separate file lies your main method
int main() {
Namespace::Class myInstance; // instantiates an instance. Note the scope resolution
Namespace::Class *myPointer = new Namespace::Class;
myInstance.incrementX(); // Calling a function on an object instance.
myPointer->incrementX(); // Calling a function on an object pointer.
(*myPointer).incrementX(); // Calling a function on an object pointer by dereferencing first
return 0;
}
-> is for pointers to a class instance
. is for class instances
:: is for classnames - for example when using a static member
The '::' is for static members.
Others have answered the different syntaxes, but please note, when you are doing your couts, you are only using ->:
int main()
{
Kwadrat* kwadrat = new Kwadrat(1,2,3);
cout<<kwadrat->val1<<endl;
cout<<kwadrat->val2<<endl;
cout<<kwadrat->val3<<endl;
return 0;
}
This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 8 years ago.
Apologies for a question that I assume is extremely basic.
I am having trouble finding out online the difference between the operator :: and . in C++
I have a few years experience with C# and Java, and am familiar with the concept of using . operator for member access.
Could anyone explain when these would be used and what the difference is?
Thanks for your time
The difference is the first is the scope resolution operator and the second is a member access syntax.
So, :: (scope resolution) can be used to access something further in a namespace like a nested class, or to access a static function. The . period operator will simply access any visible member of the class instance you're using it on.
Some examples:
class A {
public:
class B { };
static void foo() {}
void bar() {}
};
//Create instance of nested class B.
A::B myB;
//Call normal function on instance of A.
A a;
a.bar();
//Call the static function on the class (rather than on an instance of the class).
A::foo();
Note that a static function or data member is one that belongs to the class itself, whether or not you have created any instances of that class. So, if I had a static variable in my class, and crated a thousand instances of that class, there's only 1 instance of that static variable still. There would be 1000 instances of any other member that wasn't static though, one per instance of the class.
One more interesting option for when you come to it :) You'll also see:
//Create a pointer to a dynamically allocated A.
A* a = new A();
//Invoke/call bar through the pointer.
a->bar();
//Free the memory!!!
delete a;
Dynamic memory can be a little more confusing if you haven't learned it yet, so I won't go into details. Just wanted you to know that you can access members with { :: or . or -> } :)
in C++ :: is the scope resolution operator. It is used to distinguish namespaces, and static methods, basically any case you don't have an object. Where . is used to access things inside an object.
C# uses the . operator for both of them.
namespace Foo
{
public class Bar
{
public void Method()
{
}
public static void Instance()
{
}
}
}
in C# you would write code like this:
var blah = new Foo.Bar();
blah.Method();
but the equivalent C++ code would look more like this:
Foo::Bar blah;
blah.Method();
But note that the static method would also be accessed using the scope resolution operator, because you're not referencing an object.
Foo::Bar::Instance();
Where again, the C# code would only use the dot operator
Foo.Bar.Instance();
:: is for namespaces and static member access. C# uses the dot-operator for namespaces instead.
. is for non-static member access.
Not an exhaustive delineation, but it's the relevant bits that may confuse you in light of C# and Java.
For further information, see
IBM - Scope Resolution Operator
IBM - Dot Operator
:: is the scope resolution operator, so when you are resolving a scope, such as a namespace or class, you use that. For member access, you have .
The scope operator :: may be hard to understand if you don't understand namespaces or classes. A namespace is like a container for the names of various things in your code. They're generally used to disambiguate names that are common across libraries. Say both namespaces std and example have the function foobar(). So the compiler knows which function you want to use, you prepend it as either std::foobar() or example::foobar().
The :: operator can also be used when telling the compiler you want to define a function declared in a class or structure. For instance:
class foobar()
{
public:
void hello();
int number; //assume there is a constructor that sets this to 5
}
void foobar::hello()
{
cout << "Hello, world!" << endl;
}
The . operator is used when you wish to use a member of a class or structure. For instance:
foobar foo;
foo.hello();
cout << foo.number << endl;
Assuming the class is completed by writing a constructor, the output of this would be expected to be:
Hello, world!
5
You use the . operator the same in java, when accessing members of a class once its created in the program.
the :: is used in number of cases:
When you define a method in the .h/.cpp of a certain class, write
class::methodName()
either for prototyping it, or implementing it.
Also, if you don't explicitly state what namespace you use, you'd have to to use it
std::cout << "This is the output";
instead of just using cout << "This is the output;
Maybe there are more, but i don't remember right now, my C++ is a bit rusty.
In C++, :: is for identifying scope. This can mean namespace scope or class scope.
Eg.
int x;
namespace N {
int x;
struct foo {
static double x;
double y;
};
struct bar: public foo {
double y;
};
}
int main()
{
int x; // we have a local, hiding the global name
x = ::x; // explicitly identify the x in global scope
x += N::x; // explicitly identify the x in namespace N
N::foo::x = x; // set the static member of foo to our local integer
N::foo f;
f.y = f.x; // the static member is implicitly scoped by the object
f.y += N::foo::x; // or explicitly scoped
N::bar b;
assert(b.x == N::foo::x); // this static member is inherited
b.y = b.x; // we get N::bar::y by default
b.N::foo::y = b.y; // explicitly request the hidden inherited one
}
// we need to define the storage for that static somewhere too ...
int N::foo::x (0.0);
Hi I was trying to define a constant inside a class, doing it the normal or usual way doesnt seem to work
class cat
{
public:
cat();
~cat();
private:
static const int MAX_VALUE = -99999;
int Number;
public:
void OrganizeNumbers();
void SetNumbers();
};
So the solution I found after doing some research was to declare it as static but what does this means and also I want to ask it is really necesary to declare a constant, becuase as you can see it is private right? i means it can only be accessed by the class methods so why to set a constant and also I read that using static only allows you to use integral type so its actually a dissavantage... if you are thinking to make a game.
static means that the member will be shared across all instances of your object.
If you'd like to be able to have different values of a const member in different instances you'll need to use a initialization list to set it's value inside your constructor.
See the following example:
#include <string>
struct Person {
Person (std::string const& n)
: name (n)
{
// doing: 'name = n' here is invalid
}
std::string const name;
};
int main (int argc, char *argv[]) {
Person a ("Santa Claus");
Person b ("Bunny the Rabbit");
}
Further reading
[10] Constructors - parashift.com/cpp-faq
10.1 Construct Initialization List
Initialization Lists in C++
1) Declare it "private" if you're only going to use MAX_VALUE inside your class's implementation, declare it under "public" if it's part of your class's interface.
2) Back in "C" days, "static" was used to "hide" a variable from external modules.
There's no longer any need to do this under C++.
The only reason to use "static" in C++ is to make the member class-wide (instead of per-object instance). That's not the case here - you don't need "static".
3) The "const" should be sufficient for you.
4) An (older-fashioned) alternative is to define a C++ enum (instead of a "const int")
There seems to be some confusion of ideas here:
A static member doesn't have to be an integral type, the disadvantage you mention does not exist.
const and private are unrelated, just because a member can only be accessed from instances of a given class, doesn't mean that nothing is going to change it.
Being const-correct guards against runtime errors that may be caused by a value changing unexpectedly.
you have to init the const attribute in the constructor with :
cat() : MAX_VALUE(-99999) {}
(which was declare as const int MAX_VALUE;)