tags:

views:

352

answers:

5
void weight_data::rev_seq(string &seq){ 
//TODO
std::reverse(seq.begin(), seq.end());
}

In this C++ method, I think this method does not return anything, so the prefix is void, what does :: tell the relationships between weight_data and rev_seq(string &seq)? Thanks!

+1  A: 

weight_data is a namespace or class name.

JSBangs
+17  A: 

void is the return type. :: is the scope resolution operator, so it means rev_seq is inside the scope of weight_data. weight_data could be either a namespace or a class (based on what you've given, it's not possible to say which).

Jerry Coffin
"weight_data" is defined as a struct in a a.hpp file with a method called "rev_seq" (not implemented), then in a.cpp file, this method is called as what I asked in the question part
ladyfafa
sbi
@sbi: Okay, i see; can it be implemented more than once? i.e. in different cpp files, to make different implementations of the same function "rev_seq" that is from the struct "weight_data"
ladyfafa
@ladyfafa: no -- C++ has a "one definition rule" (ODR) that says any one function can only be implemented (defined) once. There are a few sort of exceptions (e.g., for inline functions) but they're only sort of exceptions, and this wouldn't fit any of them anyway.
Jerry Coffin
@ladyfafa: Generally, definitions must appear only once. (See [What is the difference between a definition and a declaration?](http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration/1410632#1410632)) However, different member functions could be implemented in different implementation files. Also, conditional compilation could be used to include one of several definitions of the same entity depending on some preconditions (e.g, the platform for which a program is compiled).
sbi
@Jerry Coffin: thanks! I basically see, if i remember correctly, seems java interfaces can be implemented more than once?
ladyfafa
@sbi, thank you for your help
ladyfafa
@ladyfafa: That's something else entirely. The equivalent to Java's interfaces in C++ would be abstract classes (classes which contain at least one pure virtual member function). As in Java, in C++ you can derive several classes from such an abstract base class, each implementing the interface in a different way. __Function definitions__, however, must only ever occur once in a program. I'm sure that's the same in Java.
sbi
@sbi: right. thanks. So, in my question post, after the implemenation of the function "rev_seq", there is no further neccesity of stating that "rev_seq" is of struct "weight_data", I mean, this function could be called anywhereelse freely?
ladyfafa
As @sbi already pointed out, a Java interface is kind of like a class that can only declare virtual functions, not (for example) any data, nor can it implement any of the functions. In that case, the "implements" is a bit more abstract.
Jerry Coffin
@ladyfafa: unless it's a static function, you have to invoke it as a member of an objects, like: `weight_data w; w.rev_seq(whatever);`
Jerry Coffin
So java interface is a class with methods that only have declaration but no implementation, if a class is going to implement this interface, then the methods in this class can be implemented in different ways, right?
ladyfafa
@ladyfafa: Please go and read [What is the difference between a definition and a declaration?](http://stackoverflow.com/questions/1410563/1410632#1410632) Basically, the compiler needs a __declaration__ of a function for you to be able to call it. The linker needs one, and only one, __definition__ of it. Class members are declared in their class' definition. They can be defined within their class' definition or outside of it. (If thy are defined within, they are implicitly `inline`. Inlined functions can be defined more than once, provided the definitions are exactly equal.)
sbi
@sbi: I read through the post, very good examples
ladyfafa
@Jerry Coffin: yes!
ladyfafa
@ladyfafa: When you derive from an abstract class (`A`), you define a new class (`B`): `class B : public A {...};` When, in this new class, you implement one of the base class' pure virtual functions (`A::f()`), you are not redefining the abstract base class' member. Instead you define a member function of the derivded class (`B::f()`) to stand in for the abstract base class' pure virtual (`A::f()`).
sbi
@ladyfafa: You might want to pick up a basic C++ introduction. Have a look at [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list).
sbi
@sbi, yes, thanks for the link
ladyfafa
"std::reverse(seq.begin(), seq.end());" will reverse the string "seq", right?
ladyfafa
@ladyfafa: As you'll likely will have found out by now, it does.
sbi
+6  A: 

In C++,

  • A::B means B is an identifier within either namespace or class type A,
  • A.B means B is a member of the struct, class, or union type an instance of which is referred to by the object or reference A, and
  • A->B means B is a member of the struct, class, or union type an instance of which is referred to by the pointer A. (It's equivalent to (*A).B.)

In some other languages, all three cases are covered by a . only.

Note that in C++, member function don't have to be implemented (defined) within their class' definition. (If they are, they are implicitly inline.) They can be, and often are, implemented in separate implementation (.cpp) files. This has the advantage that not all users of a class need to recompile when you change an implementation of one of the class' member functions. So unless weight_data is a namespace name, void weight_data::rev_seq(string &seq) {...} is such a definition of a class member outside of its class.

sbi
@sbi: that was very comprehensive, many thanks!
ladyfafa
Note: The `*` and `->` operators can be overloaded. Usually they are only overloaded for things like iterators and smart pointers. It is possible that poorly designed code will overload these operators.
Brian
@Brian: That's a very good point!
sbi
+1  A: 

The line void weight_data::rev_seq(string &seq) tells the compiler that this is the definition of the rev_seq(string &seq) member function from the weight_data. If this just said void rev_seq(string &seq) { ... } the compiler would think that a non-member function was being defined, as opposed to the rev_seq(string &seq) member function of the weight_data class.

class weight_data
{
    void rev_str(string &seq);
}

It can also mean that rev_str refers to a function that is part of namespace weight_data.

namespace weight_data
{
    void rev_str(string &seq);
}
Prabhu Jayaraman
sbi
Thanks sbi for bringing this to my notice.
Prabhu Jayaraman
A: 

Just thought of adding 2 more interesting things about the ::

a) Operator :: is both a unary and a binary operator

struct A{
   int m;
};

int x;
int main(){
   ::x;                     // Unary
   int (A::*p) = &A::m;     // Binary
}

b) $10.3/12 - "Explicit qualification with the scope operator (5.1) suppresses the virtual call mechanism."

struct A{
   virtual void f(){cout << 1;}
};

struct B : A{
   void f(){cout << 2;}
};

int x;
int main(){
   B b;
   A &ra = b;
   ra.f();     // dynamic binding, prints 2
   ra.A::f();  // suppress VF mechanism, prints 1.
}
Chubsdad