c++ publicly inherited class member cannot be used as default argument - c++

A schematic of my problem...
class A
{
public:
// etc.
protected:
uint num;
};
class B : public A
{
public:
void foo(uint x = num); //bad
};
gives this error:
error: invalid use of non-static data member ‘A::num’
error: from this location
Why does this happen, and what can I do to work around this?

I suspect this happens (based on the complaint about non-staticness) because there is no this pointer for it to use to know which instance of B it should get num from.
The Microsoft compiler (at least) allows you to specify an expression, but not a non-static member. From MSDN:
The expressions used for default
arguments are often constant
expressions, but this is not a
requirement. The expression can
combine functions that are visible in
the current scope, constant
expressions, and global variables. The
expression cannot contain local
variables or non-static class-member
variables.
Work-arounds for this are numerous and others have pointed out a few. Here's one more which you may or may not like:
void foo(uint* x = NULL) {
uint y = (x == NULL ? num : *x);
// use y...
}

You can use overloading instead of default arguments.
class A
{
public:
// etc.
protected:
uint num;
};
class B : public A
{
public:
void foo(uint x);
void foo() { foo( num ); }
};

you can create 2 foos
foo() //use num internally
foo(int x) //use x

Related

Initialize member function arguments as data members in c++

When trying to implement a class like this
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(int base = /*the value of a*/){
// some function code
}
};
I want to initialize the argument base of the function fun with the value of a (the data member of the class).
Writing int base = a or int base = this->a doesn't work.
So, I thought I could overload the function this way.
void fun(void){
fun(a);
}
void fun(int base){
// some function code
}
This will actually work, but is there any better/smarter way to do the same thing? Because I have many other functions, I want to implement the same way. And I don't want to overload each of them.
Thanks.
You can make it explicit with std::optional. Before that (or Boost.Optional or whatever), the usual solution would be to sacrifice a magic value that base could never legally take (such as -1 in the other answer).
class sample{
int a_;
public:
sample(int a = 0) : a_(a) {}
void fun(std::optional<int> base = std::nullopt){
if (!base) base = a_;
// some function code
}
};
Or, as Jarod42 suggests, something like
void fun(std::optional<int> base_opt = std::nullopt){
int base = base_opt.value_or(a_);
// some function code
}
NB.
Writing int base = a or int base = this->a doesn't work
Yeah, there is no instance at the point where the function is declared, and that's when the default expression is evaluated.
I was under the impression that private members, when they're inaccessible at the call site, would be prohibited - but that isn't correct. So the expression must be evaluated when the function is declared, with the function's own access and symbol visibility at that point, even though it is executed at the call site.
Sentinel values
This can be achieved via a "sentinel" value. If a particular integer is unused (such as -1), try:
void fun(int base = -1) {
if (base == -1) {
base = this->a;
}
// ...
}
std::optional
Another way is to wrap the input up with an std::optional:
void fun(std::optional<int> base = std::nullopt) {
if (!base) {
base = this->a;
}
// Extract actual value by using *.
int base_value = *base;
// Use base_value.
// ...
}
In the example above, base_value is the "default"-corrected int that you desired. A more elegant alternative is to use std::optional<T>::value_or to extract the value:
void fun(std::optional<int> base = std::nullopt) {
int base_value = base.value_or(this->a);
// Use base_value.
// ...
}
Overload of fun is simple and clean:
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(){
fun(a);
}
void fun(int base){
// some function code
}
};

How to call a class member function recursively from its own defintion in C++?

I'm new to C++ and I need a class member function to call itself from its own definition, like this -
class MyClass {
public: // or private: ?
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// ...
}
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
And, will there be any difference if myfunction() belongs to public: or private:?
Since the function isn't static, you already do have an instance to operate on
void MyClass::myfunction()
{
// Some code here
// ...
this->myfunction();
// ...
}
You could leave the this-> off, I was just being more clear about how the function is able to be called.
myfunction() is in the scope of the class, so you can "simply" call it:
class MyClass {
public:
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
myfunction();
}
Note, however, that this will give a stack overflow. You need a means to stop the recursion.
Member functions are actually a form of syntactic sugar. They describe a function that somehow secretly takes a pointer to an object instance which, inside the function, is accessible as this.
struct Foo {
vod bar();
};
Foo foo;
foo.bar();
What you're really doing in the call here is calling a Foo::bar(&foo); and bar is really taking a pointer Foo* this. How that's done varies from implementation to implementation, some compilers/architectures will use a special register to track the current object.
An additional piece of syntactic sugar makes all member variables and functions visible to you within a member function as though they are locally scoped
struct Foo {
int i;
int add(int n) {
return i + n;
}
int addx2(int n) {
return add(n) * 2;
}
};
What's actually happening here is:
return this->i + n;
and
return this->add(n) * 2;
This means its very easy to run into situations where you have conflicts between local and member names.
struct Foo {
int i;
Foo(int i) {
i = i; // not what you expected
}
};
For this reason, many engineers make careful use of case or prefixes or suffixes to help them distinguish members, parameters and variables.
struct Foo { // Uppercase for types and functions
int m_i; // m_ for member
Foo(int i_, int j_) {
int i = sqrt(i));
m_i = i + j_;
}
int Add(int i) {
return i_ + i;
}
};
There are various different patterns people use - some people use _name to denote a member, some use name_ and fn_ to denote members.
struct Foo {
int i_;
int add_(int _i) {
return i_ + _i;
}
};
The main thing is to be consistent.
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
Use:
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// One way to call the function again.
this->myfunction();
// ...
}
this->mufunction() can be replaced by myfunction(). Use of this is a stylistic option that makes the code easier to read for some, like me.
And, will there be any difference if myfunction() belongs to public: or private:?
No, there won't be. You can call any member function of the class from another member function.

C++ private member variables same name as ctor params

I know that many peoplpe use a prefix or suffix for private member variable names. For those who don't, but just use the name - how do you initialize them if you want to have constructor params of the same name?
By simply writing them. The rules of the language prevent problems.
struct Foo
{
Foo(int x) : x(x) {};
int x;
};
Outside the (), only the data member is in scope; inside, the function argument hides the member just as it would in a normal function body:
int x = 2;
void foo(int x)
{
// any access to `x` means the argument
}
This is one of many reasons that I do not use the m_ prefix style (or equivalent) when naming data members.
The simplest way is to use a mem-initializer list. For example
class A
{
private:
int data;
public:
A( int data ) : data( data ) {}
};
If you want to use the data member within the constructor's body then there are two approaches to distinguish the data member and the parameter
class A
{
private:
int data;
public:
A( int data ) : data( data )
{
A::data *= data;
this->data *= data;
}
};
You just initialize them in the initialization list:
struct foo
{
foo(int bar) : bar(bar) {}
private:
int bar;
};
Note that the initialization list is the only way to explicitly initialize a member in a constructor. Once you're in the body of the constructor, the member has already been initialized.
As an aside, C++ allows you to initialize a member at the point of declaration, in which case it is initialized to that value unless otherwise initialized in the constructor:
struct foo
{
foo(int bar) : bar(bar) {}
foo() {} // bar initialized to 42
private:
int bar = 42;
};
If you use an initializer list, you can simply use the same name and the compiler will understand what you mean.
Example:
Book::Book(std::string title, int year)
: title(title), year(year)
{}
The method formal name is not of high value, considering how limited it's scope is. And yet there should still be motivation to be able to instantly distinguish these items 'origins' at a glance.
It has become my practice to both
a) prefix my data attribute names with 'm_',
AND
b) prefix the method / function parameter names with 'a_' or 'an_', always striving for grammatical correctness.
LMBM::Node::Node(uint8_t a_max) : m_max (a_max) ...
void* LMBM::Node::threadEntry(void* an_objPtr) ...
void DV1::processDirent(const std::string& a_dirPath) ...
void DV1::handleDT_REG (DV::Dirent* an_ent,
const std::string& a_path) ...
FInfo (const std::string& aPfn, const int64_t& aFileSz) :
m_pfn (aPfn),
m_fileSz (aFileSz) ...
Goal - easier to read
Motivation - code is written once, read many times
I understand the special case for the ctor initializer list. But I am also confident that the use of prefixes (of your choice) do help prevent several kinds of mistakes that occur during development and maintenance.

a in-class class access the outer class's data member

I was trying to do this,
class Outer {
public:
struct inner_t {
void foo()
{
printf("%d", _x);
}
};
int _x;
};
int main()
{
Outer o;
o._x = 10;
}
The above can't compile with errors:
error: invalid use of non-static data member ‘Outer::_x’
But according to this post, inner_t can indeed access Outer::_x, what's wrong?
The problem is: inner_t does not know an instance of Outer to read _x from.
If you had written (for example):
void foo(const Outer *o)
{
printf("%d", o->_x);
}
Or if _x was a static member of Outer.
Then it should work (at least it will give no error).
You can indeed access _x of object of type Outer. You try basically to access instance field in static fashion. Pass an instance of Outer and then use it.

C++ ...when all the arguments have default values

I guess that this is a very absurd/basic question, but still:
class m
{
public:
void f(int ***);
/***/
}
void m::f(int ***a = NULL)
{
/***/
}
The call to f (as well as any function which has default values for all the arguments) doesn't accept 0 arguments. Why? How should I format the declaration then?
That works fine if the function definition is in the header file. The rule is that whoever is calling the function has to 'see' the default value.
So, I'm guessing you have the function definition in a separate source file. Assuming that's the case, just put the default in the function declaration (in the class):
class m
{
public:
void f(int *** = 0);
/***/
};
You'll also need to remove the default value from the function definition as you can only define the default in a single place (even if the value itself is the same).
This will work:
class m
{
public:
void f(int ***a = NULL);
};
void m::f(int ***a)
{
}
Default values in C++ are syntactic sugar; the compiler essentially inserts the argument for you at the callsite. This means that the compiler needs to know what the default value is, so it must be supplied by the function declaration.
This also means that if you have inheritance and virtual methods, the default values used are the ones from the static type (i.e., what type the compiler thinks the object is), not from the runtime type. For example:
class Base
{
public:
virtual ~Base() { }
virtual std::string foo(std::string s = "b") { return "Base:" + s; }
};
class Derived
: public Base
{
public:
virtual std::string foo(std::string s = "d") { return "Derived:" + s; }
};
int main(void)
{
Derived d;
Base& b = d;
std::cout << b.foo() << std::endl;
return 0;
}
will print Derived:b, not Derived:d.