This question already has answers here:
Ensuring compilation error while passing null pointer to a function
(3 answers)
Closed 3 months ago.
I am looking for a way to protect a class from receiving a NULL pointer at compiler time.
class B
{
// gives some API
}
class A
{
private:
B* ptrB_;
public:
A(B* ptrB)
{
// How can I prevent the class to be created with a null pointer?
ptrB_ = ptrB;
}
// multiple member function using: ptrB_
void A::Func1(void)
{
if(!ptrB_ )
rerturn; // I don't want to add it in every function.
...
return;
}
}
int main()
{
B tempB = NULL;
A tempA(&tempB);
}
How can I force user to always pass a pointer (not NULL) to A constructor?
Was looking at constexpr , but this forces to use static , and that's something I am trying to avoid.
To avoid the risk of NULL pointers, don't pass a pointer at all, instead use references (there are no 'null' references).
e.g.
A(B* ptrB) { ptrB_ = ptrB; } //instead of passing the address of an object
A(B& ptrB) { ptrB_ = &ptrB; } //take and store the address of the reference
Related
How do I access elements of a an array that is managed by a smart pointer?
I am getting an error
struct has no member xadj
I provided some code below.
I've documentation on smart pointers here
https://www.internalpointers.com/post/beginner-s-look-smart-pointers-modern-c
struct GraphStructure
{
std::unique_ptr<idx_t[]> xadj;
GraphStructure() {
//xadj = new idx_t[5];
std::unique_ptr<idx_t[]> xadj(new idx_t[5]);
}
void function(GraphStructure& Graph) {
int adjncyIndex = 0;
int xadjIndex = 0;
Graph.xadj[xadjIndex] = adjncyIndex;
}
It looks like you have a misnomer about how variables work in c++. In your example, you have 2 different objects of different types named xadj where one shadows the other:
struct GraphStructure {
idx_t* xadj; // A class member object named xadj of type idx_t*
GraphStructure() {
std::unique_ptr<idx_t[]> xadj(new idx_t[5]); // A function scope object called xadj
// that shadows the one above
} // At the end of this scope the xadj unique pointer is destroyed
...
void function(GraphStructure& Graph) {
Graph.xadj[xadjIndex] = adjncyIndex; // Here you use the idx_t* xadj which cannot be
// accessed with operator[], only by derefencing
// (with ->). Even if you did use this accessor,
// it would be undefined behaviour because xadj is
// not initialized.
What you are probably looking for is something like this:
struct GraphStructure {
std::unique_ptr<idx_t[]> xadj;
GraphStructure() : xadj(new idx_t[5]) {}
};
If I create a class in c++, it is possible to call a function of an object of this class, even if this class does not exists.
For example:
Class:
class ExampleClass
{
private:
double m_data;
public:
void readSomeData(double param)
{
m_data = param;
}
}
Any function where this class is used:
int main()
{
ExampleClass* myClass;
myClass->readSomeData(2.5);
}
Ofcourse this wouldn't function, because myClass is not defined.
To avoid such situations, I check if ExampleClass objects are a null_ptr
example:
void readSomeData(double param)
{
if(this == null_ptr)
return;
m_data = param;
}
But gcc says:
'this' pointer cannot be null in well-defined C++ code; comparison may
be assumed to always avaluate to false.
Ofcourse that is only a warning, but I think it is not nice to have this warning. Is there a better way to check if the pointer of a class is defined?
Testing it in the class is the wrong way, the warning is correct about that if your code is well defined then this must not be null, so the test should happen at the time when you call the member function:
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
if (myClass != nullptr) {
myClass->readSomeData(2.5);
}
return 0;
}
If a pointer must not be null at a certain part of your code then you should do it according to CppCoreGuideline: I.12: Declare a pointer that must not be null as not_null
Micorosoft provides an Guidelines Support Library that has an implementation for not_null.
Or if possible then don't use pointers at all but std::optional.
So a code setup could look like this:
#include <gsl/gsl>
struct ExampleClass {
void readSomeData(double ){}
};
// now it is clear that myClass must not and can not be null within work_with_class
// it still could hold an invalid pointe, but thats another problem
void work_with_class(gsl::not_null<ExampleClass*> myClass) {
myClass->readSomeData(2.5);
}
int main()
{
ExampleClass* myClass = nullptr; // always initialize a raw pointer to ensure
// that it does not point to a random address
// ....
work_with_class(myClass);
return 0;
}
The best way is not use pointers at all:
int main()
{
ExampleClass myClass;
myClass.readSomeData(2.5);
}
That way there's no need for any check, and in fact, checking this inside the function is moot.
If you need nullability, use std::optional instead.
Either don't use pointers as Bartek Banachewicz has pointed out, or properly initialize and check the pointer:
int main()
{
ExampleClass* myClass= 0;
if (myClass)
myClass->readSomeData(2.5);
return 0;
}
Of course you still have to add the instantiation of the object at some point, otherwise the code is nonsense.
This question already has answers here:
Why does C++ allow private members to be modified using this approach?
(6 answers)
Closed 4 years ago.
I was wondering if you could avoid secure variables in classes by assigning a pointer to a variable and then modifying the pointer to then modify the variable that is protected. This is entirely just a thought, but I've been learning about pointers recently and I dont know enough figure it out.
I don't really understand what you thought, but I think you mention to private or protected variable and using pointers to change their values. If your question is same that, then my answer is "If you really want to change private variables then you can use a pointer. To avoid that, there is no other way than to use the pointer carefully". Below is a program to show changing private variables by using pointer.
#include <iostream>
using namespace std;
class Demo
{
private:
int private_var_1;
int private_var_2;
public:
Demo()
{
private_var_1 = 1;
private_var_2 = 2;
}
void show()
{
cout<<private_var_1<<" "<<private_var_2<<" ";
}
};
int main() {
Demo d;
//now d.private_var_1 = 1 and d.private_var_2 = 2
//BUT we can completely modify d.private_var_1 and d.private_var_2
int* pointer = (int*)&d;
*pointer = 111111; //then d.private_var_1 = 111111
pointer += 1; //move the pointer to next 4 bytes, now
//the pointer point to d.private_var_2
*pointer = 222222; //then d.private_var_2 = 222222;
d.show();
return 0;
}
This question already has answers here:
Accessing static member through invalid pointer: guaranteed to "work"? [duplicate]
(3 answers)
Closed 8 years ago.
This C++ code works for my platform and compiler (Windows, GCC 4.7):
#include <stdio.h>
class A {
public:
/* ... */
int size() const
{
if ( this == NULL ) {
return 0;
}
return m_size;
}
private:
int m_size;
};
int main()
{
A* a = NULL;
printf( "%d\n", a->size() );
}
But is this code valid standard C++ and portable?
Is it Ok for method to accept this == NULL?
No, that's not OK. Any dereference of a NULL pointer is undefined behavior. It happens to work because it's not a virtual function (therefore there's no jump through the object's vtable), but that's not an excuse for doing what you're doing.
This question already has answers here:
Initializing an object to all zeroes
(12 answers)
Closed 9 years ago.
In C we set data to 0 with memset() function (Not only for the initialization).
My data could be changed by another method and I want to reuse it and then I want to set it to 0 before reusing it
Are there another way to set data to 0 in C++ other than memset()?
class MYClass : public NameSpace::ParentClass {
private:
struct mystruct data
public:
void method();
};
void MYClass::method() {
memset(&data, 0, sizeof(data)); // it's the C way. Are there another way in C++
}
In C++ you would invoke the constructor of an object, or the initialiser for primitive constructor-less objects.
Re-initialisation should actually happen very rarely (don’t reuse variables, create new ones! It makes the program flow clearer) – but when you need it you can just re-assign a new object:
data = mystruct();
It is ok to use memset on POD types, otherwise initialization must be done using constructor.
The C++ way of zeroing should look like the following:
struct mystruct
{
int i;
void Reset();
}
class MYClass : public NameSpace::ParentClass
{
private:
mystruct data
public:
void method();
};
void mystruct::Reset()
{
i = 0;
}
void MYClass::method()
{
data.Reset();
}