I've stumbled upon code using the following syntax.
int main(){
class foo{
public:
int x;
foo(int y){x=y;}
}
* bar = new foo(1);
}
Is there any purpose/consequence of using it compared to the more common
int main(){
class foo{
public:
int x;
foo(int y){x=y;}
};
foo * bar = new foo(1);
}
This is probably a matter of opinion but I think the first method is poor coding practice.
It does not impact run time behavior.
It makes the code harder to read.
Related
I currently have two unnamed classes defined in my Foo.h:
class Foo {
public:
Foo();
class {
private:
int x;
int y;
public:
int GetX() { return x; }
int GetY() { return y; }
} Sub1;
class {
private:
int x;
public:
int GetX() { return x; }
} Sub2;
}
This code compiles just fine, and it used like this:
Foo temp;
int Ax, Ay, Bx;
Ax = temp.Sub1.GetX();
Ay = temp.Sub1.GetY();
Bx = temp.Sub2.GetX();
However, now I want to move the member function definitions to the source file.The only way I know to split this class into a header file and source file, is to name the classes:
Foo.h:
class Foo {
private:
class A {
private:
int x;
int y;
public:
int GetX();
int GetY();
};
class B {
private:
int x;
public:
int GetX();
};
public:
Foo();
A Sub1;
B Sub2;
}
Foo.cpp:
int Foo::A::GetX() { return x; }
int Foo::A::GetY() { return y; }
int Foo::B::GetX() { return x; }
This code is not what I want, however, since it is ugly and I didn't want a named class in the first place.
Is it possible to split the class into a header file and source file? Or is this just bad code design?
It is, unfortunately, impossible. ยง9.3/5:
If the definition of a member function is lexically outside its class
definition, the member function name shall be qualified by its
class name using the :: operator.
Since no class name exists, no out-of-class definitions for member functions are possible. The fact that GCC allows decltype-specifiers in this context is a bug.
With gcc at least, you can do the trick using decltype:
int decltype(Foo::Sub1)::GetX() { return x; }
It is not standards compliant, though, as Columbo has already pointed out. So don't blame me, if a future version of gcc refuses to compile this. But we all now, that gcc has never been dogmatic about standards compliance, and that the gcc team has a strong tendency to keep language extensions, if they are both unambigous (which is clearly the case here) and useful to at least some programmers. Over the time, many of these gcc extensions have eventually become part of the standards.
Nonetheless, clang and probably most other compilers refuse this construct with the error message:
'decltype' cannot be used to name a declaration
But even clang can be tricked into accepting the decltype trick. We just need to do a typedef:
typedef decltype(Foo::Sub1) Sub1type;
int Sub1type::GetX() { return x; }
Of course, this is not much different to naming the unnamed classes. The advantage of the typedef solution might still be, that you can hide away the type names inside a private namespace.
#include <iostream>
using namespace std;
class A{
private:
int x;
public:
A(){
x=0;
}
A(int i)
{
x=i;
}
int Get_x(){
return x;
}
};
class B{
private:
A objA(1);
public:
objA.Get_x();
};
This is my code and it has two classes i.e A and B ..First class runs fine but in class B ..compiler gives the syntax error in the declaration of objB.....But as far as i know it should be correct ...so plz help ....thanks
This initialization is invalid for a data member:
A objA(1);
You need
A objA{1};
or
A objA = A(1);
Besides that, this kind of statement can only happen inside of a function:
objA.Get_x();
The compiler is trying to interpret A objA(1) as a function declaration, which is wrong. You may declare objA as A objA = A(1); (please note that thi is a C++11 feature, you may need to enable it before).
Also, I don't really know what objA.Get_x() should do, but this is also wrong, you can't just access a member outside of a function. Probably, you meant this:
int Get_x() {
return objA.Get_x();
}
How could I make a function only seen by the function that calls it?
define the function I want to hide as private function is not enough, as it could still be seen by other public functions in the class.
Now I use lambda expression to define anonymous function inside function. Is there any better solution?
Aside from using a lambda (which you've rejected), you could implement your function in its own compilation unit, and code the supporting function in an anonymous namespace within that compilation unit.
But that supporting function would be outside the class, so you'd have to pass it all the parameters it needed. That could become unwieldly though no worse than a long lambda capture list.
You can use a function object. For example(you can compile this, even in C++03):
#include <iostream> // only for output
class foo{
int bar(){return 0;} // Only foo can see this
public:
int operator()(){
return bar();
}
};
class baz{
public:
foo do_foo;
};
int main(){
baz a;
std::cout << a.do_foo() << std::endl;
}
the method bar is only visible by a foo.
P.S.: If you need foo to access members of baz, make it a friend.
A simmilar approach to cassiorenan would be to use static class functions and friends.
Something like this:
void Boss();
class Worker {
static void Test(){ return;}
friend void Boss();
};
void Boss(){
Worker::Test();
}
Though why would you want to do this, I don't know.
It is possible to define function inside a function without lambdas. Just define a struct that contains required function. This approach is not much better than using lambda, but at least this is straightforward and works with older compilers too.
int func() {
struct {
int hiddenFunc() {
return 1;
}
} h;
int a = h.hiddenFunc() + h.hiddenFunc();
return a;
}
As a slight variation from cassiorenan's solution, you could use a class containing one public static function (the visible function) and one static private function that could only be called from there. To avoid creation of objects of that class, it is enough to put a private constructor.
EDIT:
Per cassiorenan's comment, I can see that OP really needs methods and not functions. In that case, I would still use a dedicated class in a anonymous namespace to ensure it is not visible from elsewhere (even if my example is single file ...) friend to the class really used. So in below example, bar is the business class that would have a method with an externally hidden implementation (here relay_method), and foo is dedicated to the hidden method called with a pointer to the real object. In real world, the whole anonymous namespace and the implementation of the hidden method should be in the implementation file bar.cpp.
That way, the real implementation function priv_func can only be called from a bar object through bar::relay_method() and foo::bar_func(bar &).
#include <iostream>
class bar;
namespace {
class foo {
private:
static int priv_func(int i) {
return i * i;
}
foo() {}
public:
// only useful if true functions were needed
/* static int pub_func(int i, int j) {
return priv_func(i) + priv_func(j);
}*/
static void bar_func(bar& b);
};
}
class bar {
int x;
int x2;
public:
bar(int i): x(i) {}
void relay_method() {
foo::bar_func(*this);
}
friend class foo;
int getX2() const {
return x2;
}
};
void foo::bar_func(bar& b) {
b.x2 = foo::priv_func(b.x);
}
using namespace std;
int main() {
/* int i = foo::pub_func(3,4);
cout << i << endl;
// foo::priv_func(2); error access to private member of class foo
// foo f; */
bar b(2);
b.relay_method();
cout << b.getX2() << endl;
return 0;
}
I saw this question on SO and wondered where this kind of code can actually be used in the real time example.
struct a
{
static struct a b;
};
int main()
{
a::b;
return 0;
}
Also what is the significance of a::b;
Thanks for your inputs.
Such code can be used in implementation of the Singleton pattern. Here, one instance of type a is declared; if other instances are somehow forbidden, it is the singleton. In practice, however, i recall, they usually use less confusing syntax.
And, as for a::b, it does nothing useful. It just shows the name of the instance. A more useful example would be this:
struct a
{
static struct a b;
int data;
};
a a::b = {9};
int main()
{
int stuff = a::b.data;
printf("%d\n", stuff);
return 0;
}
I'm unfamiliar to working in c++ under linux so I have some issues, one of them is that after I write a class and try to instantiate an object of that class I get to following error : "undefined reference to Constructor_of_that_class" . This happens for every class that I write , and it happens no matter where I try to do the instantiating, even if the code compiles without any problems . What is going wrong here and what I have to do to get over this error ? Because the project that I'm working wasn't created by me I suspect that it has to do something with some settings but I don't know which.
Edit (pasted from comment):
Well if I define a class this:
class test {
public:
int a*;
test( int* a)
}
class test {
test::test( int* a)
{
this->a=a;
}
}
and then in any class of those who where previously defined I use:
test t =new test( anIntPointer);
then I get a undefined reference to test::test(int*);
I would be surprised if your code sample even compiles, so fixing all other compilation errors first would be a good start. Here is a short code sample that might help:
// Class declaration
class test
{
private:
// Member variable - should be private.
int* a;
public:
// Constructor declaration.
test(int* a);
// Inline function definition.
int getA()
{
return *a;
}
};
// Constructor declaration.
test::test( int* a)
{
this->a=a;
}
int main()
{
int i = 7;
test t(&i);
i++;
// Should return 8.
return t.getA();
}
Without code its impossible to tell, but make sure that your class definitions end with a semi-colon;
Do this:
test.h
class Test {
public:
int a*;
Test( int *a );
}; //Missing this semi colon might be your problem
test.cpp
#include "test.h"
Test::Test( int *a )
{
this->a = a;
}
int main()
{
int *anIntPointer;
Test t = new Test( anIntPointer );
return 0;
}
Don't wrap the constructor definition (the test::test() function) inside a class test block. That effectively defines a new class with the same name but it's different from the one in your header. Make it look like this:
// .h file
class test {
public:
int *a;
test( int* a)
};
// .cpp file
test::test( int* a)
{
this->a=a;
}
You should provide some code of one of your class (definition + implementation) if you want a better answer.
With the minimal explaination you provide, I think your constructor have no implementation.
Try this:
foo.h
class test {
public:
int a*;
test( int* a)
};
foo.cpp
test::test( int* a)
{
this->a=a;
}
Semantics aside from the comment I made above (I'm a little low on the whole blood sugar), you state that you're instantiating test thus:
test t =new test( anIntPointer);
the new operator returns a pointer to the object, not the object itself - you should be instantiating it:
test *t = new test(anIntPointer);
(and, going back to semantics, convention for C++ classes is a capitalised first letter, I believe :-) )
Your posted class definition is syntactically invalid. A correct equivalent would be:
class test {
public:
int *a;
test (int *a) : a(a) {}
};
Does this compile?