I have struct in class and not know how to call variables from struct, please help ;)
#include <iostream>
using namespace std;
class E
{
public:
struct X
{
int v;
};
};
int main(){
E object;
object.v=10; //not work
return 0;
}
I declared class B inside class A, how do I access it?
Just because you declare your struct B inside class A does not mean that an instance of class A automatically has the properties of struct B as members, nor does it mean that it automatically has an instance of struct B as a member.
There is no true relation between the two classes (A and B), besides scoping.
struct A {
struct B {
int v;
};
B inner_object;
};
int
main (int argc, char *argv[]) {
A object;
object.inner_object.v = 123;
}
It's not clear what you're actually trying to achieve, but here are two alternatives:
class E
{
public:
struct X
{
int v;
};
// 1. (a) Instantiate an 'X' within 'E':
X x;
};
int main()
{
// 1. (b) Modify the 'x' within an 'E':
E e;
e.x.v = 9;
// 2. Instantiate an 'X' outside 'E':
E::X x;
x.v = 10;
}
Your E class doesn't have a member of type struct X, you've just defined a nested struct X in there (i.e. you've defined a new type).
Try:
#include <iostream>
class E
{
public:
struct X { int v; };
X x; // an instance of `struct X`
};
int main(){
E object;
object.x.v = 1;
return 0;
}
You should define the struct out of the class like this:
#include <iostream>
using namespace std;
struct X
{
int v;
};
class E
{
public:
X var;
};
int main(){
E object;
object.var.v=10;
return 0;
}
If you give the struct no name it will work
class E
{
public:
struct
{
int v;
};
};
Otherwise write X x and write e.x.v
I'd like to add another use case for an internal struct/class and its usability. An inner struct is often used to declare a data only member of a class that packs together relevant information and as such we can enclose it all in a struct instead of loose data members lying around.
The inner struct/class is but a data only compartment, ie it has no functions (except maybe constructors).
#include <iostream>
class E
{
// E functions..
public:
struct X
{
int v;
// X variables..
} x;
// E variables..
};
int main()
{
E e;
e.x.v = 9;
std::cout << e.x.v << '\n';
E e2{5};
std::cout << e2.x.v << '\n';
// You can instantiate an X outside E like so:
//E::X xOut{24};
//std::cout << xOut.v << '\n';
// But you shouldn't want to in this scenario.
// X is only a data member (containing other data members)
// for use only inside the internal operations of E
// just like the other E's data members
}
This practice is widely used in graphics, where the inner struct will be sent as a Constant Buffer to HLSL.
But I find it neat and useful in many cases.
Related
So, I know you can alias types with the following:
typedef int *intPtr
But the C++ compiler can't differentiate between them:
typedef int foo
typedef int bar
foo x = 5;
bar y = 7;
int z = x + y; // checks out
I am aware that C++ does not have this without some trickery (How can I create a new primitive type using C++11 style strong typedefs?), but I found said trickery hard to read and understand.
The only plausible solution I have found is to use the Boost library, but I have a strong distaste in using external libraries.
So, is there any easily-understandable trick to make a strong typedef?
A typedef or using statement will not introduce a new type.
To get a new type you need to define one:
struct foo { int x; };
struct bar { int x; };
int main()
{
//typedef int foo;
//typedef int bar;
foo x{5};
bar y{7};
int z = x + y; // now doesn't compile, wants an operator+() defined
return 0;
}
In the above example we take advantage of aggregate initialization to allow for the use of the structs in this way.
One way to create a type that acts like a new integral type is to use a based enum. But beware: an enum is not formally an integral type. It's only its base type that is an integral type.
Also, a heads-up: I've never found this useful enough to do it.
That said, it can go like this:
#include <type_traits> // std::underlying_type
#include <utility> // std::enable_if
//----------------------------------------- Machinery:
namespace cppx {
using std::enable_if_t;
using std::underlying_type_t;
namespace impl {
inline constexpr auto is_a_typed_integer( ... ) -> bool { return false; }
} // namespace impl
template< class Type >
inline constexpr auto is_typed_integer()
-> bool
{
using impl::is_a_typed_integer;
return is_a_typed_integer( Type() );
}
namespace enum_arithmetic {
template< class Enum
, class Enabled_ = enable_if_t< is_typed_integer<Enum>(), void >
>
inline auto operator+( Enum const a, Enum const b )
-> Enum
{
using Integral = underlying_type_t<Enum>;
return Enum( Integral( a ) + Integral( b ) );
}
}
} // namespace cppx
//----------------------------------------- Usage:
namespace my {
using cppx::enum_arithmetic::operator+; // Makes it accessible via ADL.
enum class Foo: int {};
inline constexpr auto is_a_typed_integer( Foo ) -> bool { return true; }
enum class Bar: int {};
} // namespace my
//----------------------------------------- Test:
#include <iostream>
using namespace std;
auto main() -> int
{
auto x = my::Foo( 5 );
auto y = my::Bar( 7 );
(void) y;
#ifdef TRY_CONVERSION
int z = x + y; //! No implicit conversion.
(void) z;
#endif
cout << boolalpha;
cout << "Foo -> " << cppx::is_typed_integer<my::Foo>() << endl; // true
cout << "Bar -> " << cppx::is_typed_integer<my::Bar>() << endl; // false
auto x2 = x + x;
cout << int( x2 ) << endl;
#ifdef TRY_BAR
auto y2 = y + y; //! Not an arithmetic type.
(void) y2;
#endif
}
I need class definitions for class One and Two, where:
1. Objects of both the classes are able to access all the data members of both the classes.
2. Only the members of class One can access all the data members of both the classes.
//case 2
#include <iostream>
using namespace std;
class Two{
public:
float f;
int x;
};
class One: public Two{
private:
int a;
char b;
};
I have tried the 2nd part. Is it correct? And can you help me out with the 1st part.
I am not sure, what exactly it is you want. You can do it with inheritance.
I'd suggest you to read some tutorials about this, like https://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm and https://www.geeksforgeeks.org/inheritance-in-c/
You can easily try out wether it is correct or not; just compile it and look what's happening.
2:
#include <iostream>
using namespace std;
// Your classes go here
int main()
{
One o;
o.f= 1;
o.x= 2;
o.a = 10;
o.b = 11;
Two t;
t.f= 21;
t.x = 22;
cout << "One: f: " << o.f << endl;
cout << "One: x: " << o.x << endl;
// and so on
return 0;
}
For the first part, think about having a base class for both, one and two, to store data both sub-classes can access.
Thanks for answering. I have got the solution as below:
(1)
class Two {
protected:
float f;
int x;
};
class One:private Two {
int a;
char b;
};
(2)
class Two {
public:
float f;
int x;
};
class One:public Two {
public:
int a;
char b;
};
I'm trying to point a class method to a global function, i've seen this
but how i can't do it without instance?.
Consider this:
class x
{
public:
int(x::*GetVal)(int);
};
int RtX(int a)
{
return a * 4;
}
// declaration
int(x::*GetVal)(int) = (int(x::*)(int))&::Rtx; // :: global? // error
int main()
{
x a;
cout << (a.*GetVal)(4) << endl;
}
This returns me the error:
[Error] invalid cast from type 'int ()(int)' to type 'int
(x::)(int)'
x::GetX is a pointer to member. These are deeply complicated beasts, and you can't get them to point to non-member functions. The following code will work:
#include <iostream>
int RtX(int a) // Global non-member function
{
return a * 4;
}
class x
{
public:
int(x::*GetVal)(int);
// This is an instance member function which acts as a proxy and calls the
// the global function
int RtX(int a) { return ::RtX(a); }
};
int main()
{
x a;
a.GetVal =&x.RtX; // Assign the member variable. Could do this in the
// constructor. **NOTE** No casts!
std::cout << (a.*GetVal)(4) << std::endl;
}
If you find yourself reaching for a cast when dealing with function pointers and pointers-to-member-functions, stop - you are almost certainly doing it wrong, and while it will compile, it is very likely not to run properly.
Alternatively, as noted in the comments, use std::function.
#include <iostream>
#include <functional>
int RtX(int a)
{
return a * 4;
}
class x
{
public:
std::function<int(int)> GetVal;
// Initialize GetVal in the constructor.
x() : GetVal(RtX)
{}
// Alternatively, you can initialize the variable in with a default
// initialization. You can also declare the member const if you don't want to
// change it later.
const std::function<int(int)> gv = RtX;
/*
};
int main()
{
x a;
std::cout << a.GetVal(4) << std::endl;
}
Non static member functions need an instance in order to be called. You might consider using a static function member instead and if you also use std::function, you might get a simple code to assign your member function without instance:
#include <iostream>
#include <functional>
int RtX(int a)
{
return a * 4;
}
class x
{
public:
static std::function<int(int)> GetVal;
};
std::function<int(int)> x::GetVal = RtX;
int main()
{
x a;
std::cout << (a.GetVal)(4) << std::endl;
}
So, I know you can alias types with the following:
typedef int *intPtr
But the C++ compiler can't differentiate between them:
typedef int foo
typedef int bar
foo x = 5;
bar y = 7;
int z = x + y; // checks out
I am aware that C++ does not have this without some trickery (How can I create a new primitive type using C++11 style strong typedefs?), but I found said trickery hard to read and understand.
The only plausible solution I have found is to use the Boost library, but I have a strong distaste in using external libraries.
So, is there any easily-understandable trick to make a strong typedef?
A typedef or using statement will not introduce a new type.
To get a new type you need to define one:
struct foo { int x; };
struct bar { int x; };
int main()
{
//typedef int foo;
//typedef int bar;
foo x{5};
bar y{7};
int z = x + y; // now doesn't compile, wants an operator+() defined
return 0;
}
In the above example we take advantage of aggregate initialization to allow for the use of the structs in this way.
One way to create a type that acts like a new integral type is to use a based enum. But beware: an enum is not formally an integral type. It's only its base type that is an integral type.
Also, a heads-up: I've never found this useful enough to do it.
That said, it can go like this:
#include <type_traits> // std::underlying_type
#include <utility> // std::enable_if
//----------------------------------------- Machinery:
namespace cppx {
using std::enable_if_t;
using std::underlying_type_t;
namespace impl {
inline constexpr auto is_a_typed_integer( ... ) -> bool { return false; }
} // namespace impl
template< class Type >
inline constexpr auto is_typed_integer()
-> bool
{
using impl::is_a_typed_integer;
return is_a_typed_integer( Type() );
}
namespace enum_arithmetic {
template< class Enum
, class Enabled_ = enable_if_t< is_typed_integer<Enum>(), void >
>
inline auto operator+( Enum const a, Enum const b )
-> Enum
{
using Integral = underlying_type_t<Enum>;
return Enum( Integral( a ) + Integral( b ) );
}
}
} // namespace cppx
//----------------------------------------- Usage:
namespace my {
using cppx::enum_arithmetic::operator+; // Makes it accessible via ADL.
enum class Foo: int {};
inline constexpr auto is_a_typed_integer( Foo ) -> bool { return true; }
enum class Bar: int {};
} // namespace my
//----------------------------------------- Test:
#include <iostream>
using namespace std;
auto main() -> int
{
auto x = my::Foo( 5 );
auto y = my::Bar( 7 );
(void) y;
#ifdef TRY_CONVERSION
int z = x + y; //! No implicit conversion.
(void) z;
#endif
cout << boolalpha;
cout << "Foo -> " << cppx::is_typed_integer<my::Foo>() << endl; // true
cout << "Bar -> " << cppx::is_typed_integer<my::Bar>() << endl; // false
auto x2 = x + x;
cout << int( x2 ) << endl;
#ifdef TRY_BAR
auto y2 = y + y; //! Not an arithmetic type.
(void) y2;
#endif
}
The following looks like a compilation error :
struct : Base { };
Yet when used [1] it seems to work :
#include <iostream>
using namespace std;
template<bool B>
struct A
{
struct : std::integral_constant<bool, B> {
} members;
};
int main()
{
A<true> a;
cout << a.members.value << endl;
return 0;
}
In c++ is it valid for unnamed structures to inherit? Are there any examples where this is userful?
[1] Disclaimer: I'm not pretending the provided example is useful. I rarely use unnamed structs, and when I do they're usually bundling together some built-in member variables, in order to provide a cleaner interface for a class. The question came up from the observation that memberspaces need not be nammed structures
Unnamed classes can inherit. This is useful, for example, in situations when you must inherit in order to override a virtual function, but you never need more than one instance of the class, and you do not need to reference the derived type, because a reference to the base type is sufficient.
Here is an example:
#include <iostream>
using namespace std;
struct Base {virtual int process(int a, int b) = 0;};
static struct : Base {
int process(int a, int b) { return a+b;}
} add;
static struct : Base {
int process(int a, int b) { return a-b;}
} subtract;
static struct : Base {
int process(int a, int b) { return a*b;}
} multiply;
static struct : Base {
int process(int a, int b) { return a/b;}
} divide;
void perform(Base& op, int a, int b) {
cout << "input: " << a << ", " << b << "; output: " << op.process(a, b) << endl;
}
int main() {
perform(add, 2, 3);
perform(subtract, 6, 1);
perform(multiply, 6, 7);
perform(divide, 72, 8);
return 0;
}
This code creates four anonymous derivations of Base - one for each operation. When the instances of these derivations are passed to the perform function, the proper override is called. Note that perform does not need to know about any of the specific types - the base type with its virtual function is enough to complete the process.
Here is the output of running the above code:
input: 2, 3; output: 5
input: 6, 1; output: 5
input: 6, 7; output: 42
input: 72, 8; output: 9
Demo on ideone.
Your first example, because it doesn't declare anything, shows an attempt at an anonymous struct (which is not allowed - 7/3) rather than an unnamed one (which is).
The grammar in 9/1 of the C++11 standard seems to allow an unnamed class to have a base, so I think your second example is fine.