As the unmanaged C++ is feel free to locate to different object.
Such as the pointer to an array
int pt[50];
int* pointer = pt;
We can directly use *pointer to get the first value of the element in the array.
Thus, we can also use *(pointer++) in order to point to the second element.
However, if it is possible to directly use ^(pointer+5) to get the sixth element of the array?
The example is as follow.
array<int>^ pt = gcnew array<int>(50);
int^ pointer = pt;
How can I use the pointer as a medium to access different element in the array?
here is a slightly different approach that may be of use ...
It uses interior pointer arithmetic (to traverse an array).
Hope this helps.
using namespace System;
ref class Buf
{
// ...
};
int main()
{
array<Buf^>^ array_of_buf = gcnew array<Buf^>(10);
// Create a Buf object for each array position
for each (Buf^ bref in array_of_buf)
{
bref = gcnew Buf();
}
// create an interior pointer to elements of the array
interior_ptr<Buf^> ptr_buf;
// loop over the array with the interior pointer
// using pointer arithmetic on the interior pointer
for (ptr_buf = &array_of_buf[0]; ptr_buf <= &array_of_buf[9]; ptr_buf++)
{
// dereference the interior pointer with *
Buf^ buf = *ptr_buf;
// use the Buf class
}
}
reference: C++/CLi the visual c++ language for .net (pg 99)
here is another example from: https://msdn.microsoft.com/en-us/library/y0fh545k.aspx
// interior_ptr.cpp
// compile with: /clr
using namespace System;
ref class MyClass {
public:
int data;
};
int main() {
MyClass ^ h_MyClass = gcnew MyClass;
h_MyClass->data = 1;
Console::WriteLine(h_MyClass->data);
interior_ptr<int> p = &(h_MyClass->data);
*p = 2;
Console::WriteLine(h_MyClass->data);
// alternatively
interior_ptr<MyClass ^> p2 = &h_MyClass;
(*p2)->data = 3;
Console::WriteLine((*p2)->data);
}
Related
I am trying to std::bind class functions in combination of std::unique_ptr and I have a lot of trouble getting it to work
First I have two classes
class simpleClass{
public:
simpleClass(int x){
this->simpleNumber = x;
}
int simpleNumber;
simpleClass(const simpleClass &toBeClone){
this->simpleNumber = toBeClone.simpleNumber;
}
simpleClass clone(){
simpleClass *cloned = new simpleClass(*this);
return *cloned;
}
};
class className{
public:
className(doube input){
this->someVariable = input;
}
void someFunction(std::vector<double> x, double c, std::unique_ptr<simpleClass> &inputClass, std::vector<double> &output){
std::vector<double> tempOutput;
for(int i = 0; i<x.size(); i++){
tempOutput.push_back(x[i] + c * this->someVariable + inputClass->simpleNumber);
}
output = tempOutput;
}
double someVariable;
className(const className &toBeClone){
this->someVariable = toBeClone.someVariable;
}
className clone(){
className *cloned = new className(*this);
return *cloned;
}
};
They are both some standard class, but I also implement a clone function to duplicate an initialized class. While cloning, I need to ensure that the original class and the cloned class points to different address. So I use std::unique_ptr to ensure this.
The is the main function, which also shows how I "clone"
int main(){
className testSubject(5);
std::vector<std::unique_ptr<className>> lotsOfTestSubject;
simpleClass easyClass(1);
std::vector<std::unique_ptr<simpleClass>> manyEasyClass;
for(int i = 0; i<10; i++){
std::unique_ptr<className> tempClass(new className(testSubject.clone()))
lotsOfTestSubject.push_back(std::move(tempClass));
std::unique_ptr<simpleClass> tempEasyClass(new simpleClass(easyClass.clone()))
manyEasyClass.push_back(std::move(tempEasyClass));
}
std::vector<std::vector<<double>> X; //already loaded with numbers
double C = 2;
std::vector<std::vector<<double>> OUT;
for(int i = 0; i<10; i++){
std::vector<double> tempOUT;
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
OUT.push_back(tempOUT);
//Here if I want to bind
/*
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
*/
}
return 0;
}
The reason why I "clone" is because both simpleClass and className takes a lot of time for construction in my implementation, and I need a lot of them. And Since many of them will be initialized with the same parameters, I figured this is the easiest way to do so.
The code above works, but I am trying to improve the speed of the loop. The following line is where most of the computation takes place.
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
So I am attempting to use threads to delegate the work , and as far as I know, I need to std::bind first. So I tried
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
But the compiler prints error like this
/usr/include/c++/5/tuple|206| recursively required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 1ul; _Head = std::vector<double>; _Tail = {double, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::vector<double>}]’|
/usr/include/c++/5/tuple|108|error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = className; _Dp = std::default_delete<className>]’|
I have no idea what this means as I just started self teaching c++. Any feedback and guidance is much appreciated.
I am using c++11 and g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Update
Thanks #rafix07, tried your solution and it works fine. but then I tried to do
auto theBinded = std::bind(&className::someFunction, &lotsOfTestSubject[i],
X[i], C, std::ref(manyEasyClass[i]), tempOUT);
std::thread testThread(theBinded);
and eventually want to testThread.join()
But the compiler says
error: pointer to member type ‘void (className::)(std::vector<double>, double, std::unique_ptr<simpleClass>&, std::vector<double>&)’ incompatible with object type ‘std::unique_ptr<className>’|
#kmdreko Thanks for you point out! I haven't notice memory leak yet, but I will fix it. Do I just use this?
std::unique_ptr<className> tempClass = new className(testSubject);
EDIT
If you want to call someFunction on instance stored in lotsOfTestSubject you need to pass pointer to className object on which this method will be called, so the line below
std::bind(&className::someFunction, lotsOfTestSubject[i]
should be replaced by:
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
^^^
Second change is to use std::ref to pass original instance of unique_ptr of manyEasyClass instead of its copy. std::bind always copies or moved its arguments (see reference), but unique_ptr is non-copyable, that is why compilation failed.
So fixed line looks:
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
X[i], C, std::ref(manyEasyClass[i]), std::ref(tempOUT));
tempOUT also must be passed by std::ref because you want to modify this vector by call operator() on functor created by bind.
LIVE DEMO
std::string (std::basic_string) have assignment operator for 'char' type.
But, for this reason, std::string may assign any integral types.
See little example.
#include <string>
enum MyEnum{ Va = 0, Vb = 2, Vc = 4 };
int main(){
std::string s;
s = 'a'; // (1) OK - logical.
s = Vc; // (2) Ops. Compiled without any warnings.
s = true; // (3) Ops....
s = 23; // (4) Ops...
}
Q: How disable (or add warning ) (2, 3, 4) situations ??
There is a related Question
Given the constraints of C++03 and GCC 4.8 as in the tags, I could not get -Wconversion to do anything useful (and in GCC 7 it doesn't even generate the warnings for me despite telling it that I'm using --std=c++03).
As such, there's a good practical solution that requires only minimal change at your calling site:
Proxy the assignment via a class object that wraps your string and that allows assignment from char but disallows it from int:
#include <string>
enum MyEnum{ Va = 0, Vb = 2, Vc = 4 };
struct string_wr {
string_wr (std::string& s) : val(s) {}
operator std::string& () const { return val; }
// we explicitly allow assigning chars.
string_wr& operator= (char) { return *this; }
// ww explicitly disable assigning ints by making the operator unreachable.
private:
string_wr& operator= (int);
private:
std::string& val;
};
int main(){
std::string s;
s = 'a'; // (1) OK - logical.
s = Vc; // (2) Ops. Compiled without any warnings.
s = true; // (3) Ops....
s = 23; // (4) Ops...
string_wr m(s); // this is the only real change at the calling site
m = 'a'; // (1) OK - logical.
m = Vc; // (2) Should fail with "assignment is private" kind of error.
m = true; // (3) Should fail...
m = 23; // (4) Should fail...
}
However, if your final goal is to specifically get warnings or errors when using std::string, your best option in C++03 is to patch the <string> header to add the private int-assignment operator shown in the class above. But that means patching a system header and the procedure and results will be dependant on your compiler version (and will have to be repeated in each installation and compiler version).
I have a simple struct, that has all constructors defined.
It has an int variable, each constructor and assign operator prints address of *this, current value of int and a new value of int.
Move and copy assign operators and constructors also print adress of passed value.
#include <iostream>
struct X
{
int val;
void out(const std::string& s, int nv, const X* from = nullptr)
{
std::cout<<this<<"->"<<s<<": "<<val<<" ("<<nv<<")";
if (from)
std::cout<<", from: ["<<from<<"]";
std::cout<<"\n";
}
X(){out("simple ctor X()",0); val = 0;}
X(int v){out("int ctor X(int)", v);val = v; }
X(const X& x){out("copy ctor X(X&)", x.val, &x);val = x.val; };
X&operator = (const X& x){out("copy X::operator=()", x.val, &x); val = x.val; return *this;}
~X(){out("dtor ~X", 0);}
X&operator = (X&& x){out("move X::operator(&&)", x.val, &x); val = x.val; return *this;}
X(X&& x){out("move ctor X(&&x)", x.val, &x);val = x.val;}
};
X copy(X a){return a;}
int main(int argc, const char * argv[]) {
X loc{4};
X loc2;
std::cout<<"before copy\n";
loc2 = copy(loc);
std::cout<<"copy finish\n";
}
output:
0xffdf7278->int ctor X(int): 134523184 (4)
0xffdf727c->simple ctor X(): 134514433 (0)
before copy
0xffdf7280->copy ctor X(X&): 1433459488 (4), from: [0xffdf7278]
0xffdf7284->move ctor X(&&x): 1433437824 (4), from: [0xffdf7280]
0xffdf727c->move X::operator(&&): 0 (4), from: [0xffdf7284]
0xffdf7284->dtor ~X: 4 (0)
0xffdf7280->dtor ~X: 4 (0)
copy finish
0xffdf727c->dtor ~X: 4 (0)
0xffdf7278->dtor ~X: 4 (0)
What's the purpose of creating an additional object with (in this example) address 0xffdf7284?
If you look at the copy elision rules from cppreference.com, you can notice that there are two case where the compilers are required to omit the copy- and move- constructors of class objects even if copy/move constructor and the destructor have observable side-effects (which yours do, due to the printouts). The first is clearly irrelevant to this case. The second is
In a function call, if the operand of a return statement is a prvalue and the return type of the function is the same as the type of that prvalue.
With the example given of:
T f() { return T{}; }
T x = f();
This seems more relevant, however, note that in your case, the operand of the return statement is not a prvalue. So in this case, no mandatory elision applies.
The set of steps, when callingloc2 = copy(loc);, is as follows:
a is copy-constructed from loc.
The return value of the function is move-constructed from a.
loc2 is move-assigned from the return value.
Logically, a person could look at the code and deduce that fewer operations need to be done (in particular, when looking at copy, it's obvious that, logically, an assignment from loc to loc2 is enough), but the compiler doesn't know that the purpose of your code isn't to generate the side effects (the printouts), and it is not breaking any rules here.
This is the code.
int main()
{
unique_ptr <int> p {nullptr};
int val = 100;
p = &val; // Not working - compilation error
p = move(&val); // Not working - compilation error
cout << *p;
return 0;
}
What is the correct way?
Only dynamically allocated objects should be assigned to unique_ptrs, because the unique_ptr may try to delete the object.
As for the actual question, the reset() function of unique_ptr is used to reassign the pointer.
With unique_ptr::reset:
p.reset(&val);
Of course in this particular case this will result in undefined behavior when p goes out of scope and it tries to delete the int, but that's another matter.
all,
If you use boost pool library, how would you replace the following statement:
MyStruct *someStruct = (MyStruct *) calloc(numOfElements, sizeof(MyStruct));
If it was for one element, I would do:
boost::object_pool<MyStruct> myPool;
MyStruct *someStruct = myPool.malloc();
but since "numOfElements" is a variable, I have the feeling executing a loop of malloc() is not a good idea?
I'd say you need to use pool_alloc interface:
static pointer allocate(size_type n);
static pointer allocate(size_type n, pointer);
static void deallocate(pointer ptr, size_type n);
Sample from http://www.boost.org/doc/libs/1_47_0/libs/pool/doc/interfaces.html
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
} // Exiting the function does NOT free the system memory allocated by the pool allocator
// You must call
// boost::singleton_pool<boost::pool_allocator_tag, sizeof(int)>::release_memory()
// in order to force that