How to access correct class member? - c++

I've been running across this snippet of code and after execution I found out that everything compiles and executes fine (the int code member of the derived class is set to 65). However I was wondering how would one be able to access the char code member of the derived class?
#include <iostream>
using namespace std;
class base {
public:
base() : code('B') { }
char code;
};
class derived : public base
{
public:
int code;
};
int main(void)
{
derived d;
d.code = 65;
std::cout << d.code;
};

By specifying the correct scope for the base member variable using a qualified name lookup, as follows:
d.base::code = 'x'
std::cout << d.base::code << '\n';
See this section on qualified name lookups for more details.

Related

C++'s double colon used after a class name instead of a namespace

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.

Access specifier toward scoped base method

In the following complete program:
#include <vector>
class Derived : private std::vector<int> {
public:
void f();
};
void Derived::f() {
Derived d;
d.std::vector<int>::push_back(0);
}
int main() {
Derived d;
d.f();
}
the line
d.std::vector<int>::push_back(0);
can be replaced by
d.vector<int>::push_back(0);
and the compilation would complete w/o warning both in gcc 7 and clang 6.
I don't understand why the std:: part of the scope resolution is optional, since there's no using namespace std declaration.
As others already mentioned:
Do not inherit from STL!
See this and this and read Effective c++ book.
Apart from the derivation from STL, it could be an everyday problem. I think you are searching for how qualified name lookup works.
Consider the following code
#include <iostream>
#include <string>
namespace myNamespace {
namespace nested {
class base {
protected:
std::string print() { return "Fantastic"; };
static const int four= 4;
};
}
}
class derived : private myNamespace::nested::base
{
public:
// no need to extra qualify base class methods, since derived access the scope of the base class
std::string doStuff() { return print() + std::to_string(four); };
};
int main()
{
derived d;
std::cout << d.doStuff();
}
It has the same structure, deriving from something that is a part of a namespace. As you noticed, in the derived there is no need to extra qualify the print method. However, the following is completely legal call in the doStuff method:
print();
base::print();
myNamespace::nested::base::print();
Note that simply nested::base::print(); is not legal - myNamespace should be used.
Ps. I compiled with MSVC 143, and always produced this output:
Fantastic4

Access to class inside Union

I have the declaration of class Ainside a third party library, so I can't modify it.
I need to use the declaration of class B to pass it to a method, is there a way to do it without modifying class A?
When I try this:
#include <iostream>
using namespace std;
class A
{
public:
union {
class B
{
public:
int x;
};
}un;
};
void foo(A::B & test)
{
}
int main() {
A::B test;
test.x=10;
cout << test.x << endl;
return 0;
}
I get the error:
error: B is not a member of A
Live Example!
My assumption is that it happens because B is in a unnamed namespace.
PS: If I could modify the declaration of the union
from:
union {...
to:
union T {...
This will be done simple by:
A::T::B test;
You can get the type of the union using decltype, then you can access B:
decltype(std::declval<A&>().un)::B test;
coliru example

Member is inaccessible

class Example{
public:
friend void Clone::f(Example);
Example(){
x = 10;
}
private:
int x;
};
class Clone{
public:
void f(Example ex){
std::cout << ex.x;
}
};
When I write f as a normal function, the program compiles successful. However, when I write f as a class member, this error occurs.
Screenshot:
The error you're seeing is not a root-cause compilation error. It is an artifact of a different problem. You're friending to a member function of a class the compiler has no earthly clue even exists yet,much less exists with that specific member.
A friend declaration of a non-member function has the advantage where it also acts as a prototype declaration. Such is not the case for a member function. The compiler must know that (a) the class exists, and (b) the member exists.
Compiling your original code (I use clang++ v3.6), the following errors are actually reported:
main.cpp:6:17: Use of undeclared identifier 'Clone'
main.cpp:17:25: 'x' is a private member of 'Example'
The former is a direct cause of the latter. But doing this instead:
#include <iostream>
#include <string>
class Example;
class Clone
{
public:
void f(Example);
};
class Example
{
public:
friend void Clone::f(Example);
Example()
{
x = 10;
}
private:
int x;
};
void Clone::f(Example ex)
{
std::cout << ex.x;
};
int main()
{
Clone c;
Example e;
c.f(e);
}
Output
10
This does the following:
Forward declares Example
Declares Clone, but does not implement Clone::f (yet)
Declares Example, thereby making x known to the compiler.
Friends Clone::f to Example
Implements Clone::f
At each stage we provide what the compiler needs to continue on.
Best of luck.

Structure initialization in class objects

How do I initialize the structure variables of type class objects? I have the following code:
#include<iostream>
using namespace std;
class bitmap {
public :
bitmap() { clear() ;}
get();
set();
clear();
static const int a=10;
};
bitmap::get() {
};
struct bitmap_list {
bitmap_list_value _value;
}
int main()
{
bitmap bitmap_list_value;
bitmap_list bbbb;
bbbb. _value=bitmap_list_value.a;
cout << bbbb._value << endl;
}
Is this code correct, or is it possible to initialize the structure containing the class objects? This is the error I receive:
>error: ‘struct error: ‘_bitmap_list_value’ does not name a type
>error:bitmap_list’ has no member named ‘_value’
No, this code is not correct. You're referencing a type bitmap_list_value which is never declared.
Based on your comment ("bitmap_list_value is object of class bitmap"), it sounds as if you also have this, but haven't included it in your question's code for some reason:
typedef bitmap bitmap_list_value;
But yes, of course you can include members of class types inside structs. A struct is more or less a class with all fields made public by default, you can define methods inside structs just as you can with classes, and so on.