If I have a class:
class A{
public:
A();
void print();
private:
int value;
};
A::A() {value = 0;}
void A::print() {cout << value << endl;}
What is the complete name of the :: symbol in the last 2 lines?
What is the complete name of the :: symbol in the last 2 lines?
It's "scope resolution operator".
Does anyone know the answer?
Yes.
Is this the weirdest question you ever been asked?
No.
It's called the scope resolution operator.
It's called scope resolution operator.
You'd like to know what you could write instead of ::? Well, there is no alternative that always works. For your example, it is possible to just define those member functions in the body of your class, that would be the inline-style of defining a class:
class A{
int value;
public:
A() {
value = 0;
}
void print() {
cout << value << endl;
}
};
That way, you obviously have no way to put the definition in a different file, so it's not possible to compile them separately.
At other times, when :: is used to resolve a namespace rather than a class, you can replace that with either reopening that namespace or pulling it into scope with using namespace.
Related
I am trying to understand a c++ program listed here. I am confused about the second use of double colons on lines 86-87:
using TransformType = itk::AffineTransform< ScalarType, Dimension >;
TransformType::Pointer transform = TransformType::New();
It looks like TransformType is a user-defined type. How would one use it before New()? I heard that the double-colon is to be used following a namespace, but here, TransformType is a type (namely class) rather than a namespace. Can someone clarify --- should double colon be always used after a namespace in C++? Would it possible to use a dot (like in Java) instead?
You use the scope resolution operator (::) to name something in a namespace, or in a class, or in a scoped enum; this is called qualified lookup.
#include <iostream>
namespace N
{
int x = 0;
}
int main()
{
std::cout << N::x << '\n';
}
Using it with a class usually means you're referring to some static member, because otherwise you'd generally be using objectInstance.member instead.
#include <iostream>
class C
{
public:
static int x;
}
int C::x = 0;
int main()
{
std::cout << C::x << '\n';
}
Though, within a non-static member function, there are still uses for ::, such as disambiguating between names that exist concurrently in different bases.
class Base
{
public:
void foo() {}
};
class Derived : public Base
{
public:
void foo()
{
// Do base version (omitting Base:: will just call this one again!)
Base::foo();
// Now maybe do other things too
}
};
int main()
{
Derived obj;
obj.foo();
}
… or for naming a non-static member in a scenario where an object context is not required:
#include <iostream>
class C
{
public:
int x;
}
int main()
{
std::cout << sizeof(C::x) << '\n';
decltype(C::x) y = 42;
}
It's needed with scoped enums because, well, they're scoped; that's the whole point of them. They don't leak into the surrounding scope but have their own which as a result you need to specify specifically.
enum class E
{
Alpha,
Bravo,
Charlie
};
void foo(E value) {}
int main()
{
foo(E::Alpha);
}
Some languages let you access static members of classes with the type name followed by ., just like you'd access non-static members of classes with the object name followed by .. C++ is not one of those languages.
By the way, this is legal:
#include <iostream>
class C
{
public:
int x = 42;
};
int main()
{
C obj;
std::cout << obj.C::x << '\n';
// ^^^ what?!
}
Adding scope resolution to x here is not necessary, because the language already knows from the obj. that you're asking for a member of a class C. But you can still add it if you want. It's just usually "done for you" in this case.
#include <iostream>
using namespace std;
struct A
{
A()
{
cout << "A::A()" << endl;
}
};
int A()
{
cout << "void A()" << endl;
return 0;
}
int main()
{
auto v = A();
}
The output is:
void A()
Why does C++ allow a function and a class have a same name?
I believe this comes down to backwards compatibility with C.
In C, when you declare a struct like you did, you then have to refer to it as struct A, not just A. For example:
void A() {}
struct A {};
void f()
{
A();
struct A x; // works fine
A y; // does not compile
}
In this context, it makes sense to allow A to mean two different things, because it's always clear which one you mean, depending on whether you used struct or not.
In C++, structs (and classes) can be referenced directly, without the need to use the struct keyword. This introduces the ambiguity you're concerned about, but the alternative is that valid C code like the one above would not be valid C++ code, which is even worse.
Why? Because that's the way the language is! The A::A() function belongs in a different "domain" than A().
It's similar to namespaces, where the same name can exist in multiple domains.
It's also somewhat similar to having a thousand different functions (or scopes) all having their own loop counter called i.
I'm watching some video tutorials on C++ and i know you must define a function / class before it is used or called. But I like having my main() function at the top, and everything else below the main function. I know if i define a function below the main function I must declare it before it is used, but what about a class? What do I need to put above my main function to use my class below the main function.
#include <iostream>
using namespace std;
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
I tried defining my class by placing this right before main():
class ClassOne;
but it doesn't work.
This is why header files are normally used in C++. When you're saying ClassOne one, the compiler needs to know what the class looks like to create an object of that type. It's not enough to know that the class exists somewhere (that is enough if all you want is a pointer). So the compiler needs to already have read the definition of the class.
Your class has to be defined before it is first used. Without putting it explicitly before main, the usual way is to create a header file. So you create ClassOne.h with the class declaration, and you have #include "ClassOne.h at the top of your file. In this situation the actual methods of the class would normally be in another source file, ClassOne.cpp.
A class MUST be "complete" when you create an instance of it. So there is no way you can use the class before you have defined the whole content of the class.
It is possible to do something like this:
class ClassOne;
ClassOne* make_class_one();
void use_class(ClassOne *x);
int main()
{
ClassOne* one = make_class_one();
use_class(one);
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
ClassOne* make_class_one()
{
return new ClassOne; // Bad idea, use uniqe_ptr, but I'm lazy.
}
void use_class(ClassOne *x)
{
x->coolSaying();
}
But in general, we don't want to do that.
One scenario where the class definition after the main() function makes sense:
#include <iostream>
using namespace std;
void f();
int main()
{
f();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
void f()
{
ClassOne one;
one.coolSaying();
}
(note: all other answers are correct, but you may find this useful)
I discovered this idiom to invert the order of main and secondary function classes. I use to share small code with colleagues, everybody expects the core of the code (i.e. main) to be on top so they can edit it quickly. It works with classes and functions (without need of declaration) of course. Usually I can leave the preamble (first #includes) because those have include guards in most cases.
#include <iostream>
using namespace std;
#ifdef please_see_definitions_below_main
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
#else
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
#define please_see_definitions_below_main
#include __FILE__
#endif
I use the tag please_see_definitions_below_main so it serves as comment also, but if you don't like it you can use something shorter, like AFTER.
You cannot create an actual instance of the type (variable, value member) until the type is fully defined, as its size is not known. There is no way around that, but there is a lot you can already do with a pointer to an incomplete type.
When forward declarations of functions work in a source file (.cpp), why would the same doesn't work for classes ?
Thanks.
// main.cpp
void forwardDeclaredFunction() ; // This is correct
class One ; // Why this would be wrong
int One:: statVar = 10 ;
void
One :: anyAccess() {
std::cout << "\n statVar:\t " << statVar ;
std::cout << "\n classVar:\t" << classVar ;
}
class One {
public:
void anyAccess() ;
static int statVar ;
private:
int classVar ;
} ;
int main (int argc, char * const argv[]) {
One *obj = new One ;
return 0;
}
void forwardDeclaredFunction() {
}
Forward declaration can work for classes too:
class Foo;
class Bar {
public:
Foo *myFoo; // This has to be a pointer, thanks for catching this!
};
class Foo {
public:
int value;
};
The above code shows a forward declaration of the Foo class, using a variable of type Foo* in another class (Bar), then the actual definition of the Foo class. C++ doesn't care if you leave things unimplemented as long as you implement them before using its code. Defining pointers to objects of a certain type is not "using its code."
Quick, dirty reply but I hope it helps.
Edit: Declaring a non-pointer variable of a class thats unimplemented will NOT compile as the replies stated out. Doing so is exactly what I meant by "using its code." In this case, the Foo constructor would be called whenever the Bar constructor is called, given that it has a member variable of type Foo. Since the compiler doesn't know that you plan on implementing Foo later on, it will throw an error. Sorry for my mistake ;).
The forward declaration class One; allows you to refer to the class itself but not to any of its members. You have to put all definitions of class members after the full declaration of the class. (Or inside, of course.)
Place your member declaration of your class before the member implementations.
class One {
public:
void anyAccess() ;
static int statVar ;
private:
int classVar ;
} ;
int One:: statVar = 10 ;
void
One :: anyAccess() {
std::cout << "\n statVar:\t " << statVar ;
std::cout << "\n classVar:\t" << classVar ;
}
You're getting the error message on int One:: statVar = 10 ; NOT on the forward declaration, which is fine.
The compiler needs to know the full definition of the class before you can define static members like that - a forward declaration is insufficient (it needs to be able to confirm that the type is correct from the class definition).
You'll need to move your static attribute definition below the class definition.
The compiler reads stuff from beginning to end, and generates code as it goes. (Some compilers may not do this, but they should behave as if they did.) But before the class is defined, the compiler doesn't know that One::statVar or One::anyAccess should exist, or whether the function is virtual, static, or what. It needs to know that stuff in order to generate code.
when you create 2 class & one function can access data from on class to another class
then it is a friend function
forword declaration is use to know which class in next
class abc;
class xyz
{
data member;
public:
friend void getdata();
other member function
}
class abc
{
data member
public:
friend void getdata();
}
I was trying to write up a class in c++, and I came across a rather odd problem: calling outside functions inside of a class that have the same name as the class. It's kinda confusing, so here's an example:
void A(char* D) {
printf(D);
}
class A
{
public:
A(int B);
void C();
};
A::A(int B) {
// something here
}
void A::C() {
A("Hello, World.");
}
The compiler complains at the second to last line that it can't find a function A(char*), because it is inside the class, and the constructor has the same name as the function. I could write another function outside, like:
ousideA(char* D) {
A(D);
}
And then call outsideA inside of A::C, but this seems like a silly solution to the problem. Anyone know of a more proper way to solve this?
::A("Hello, world.");
should work fine. Basically it is saying "use the A found in the global namespace"
Use the scope resolution operator :: to access the name from the global scope:
void A::C() {
::A("Hello, world.");
}
I suggest you use namespaces. Put your class in a different namespace than the function.
namespace my_namespace1
{
void A() {}
}
namespace my_namespace2
{
struct A {};
}
int main()
{
my_namespace1::A();
my_namespace2::A my_a;
}
Of course, the real question is, why do you have a class and a function with a different name? A good easy rule is to make classes named WithABeginningCapitalLetter and functions withoutOne. Then you will never have this problem. Of course, the STL doesn't do this...