Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向类对象的Void指针:函数内部的初始化_C++_Class_Pointers_Void Pointers - Fatal编程技术网

C++ 指向类对象的Void指针:函数内部的初始化

C++ 指向类对象的Void指针:函数内部的初始化,c++,class,pointers,void-pointers,C++,Class,Pointers,Void Pointers,我试图创建一个指向类对象的空指针,并在函数中初始化它。不幸的是,该类的数组成员无法逃逸函数,即初始化后无法访问该函数 在下面的代码中,对打印位置的第一次调用(在初始化函数内部)工作正常,但是,从初始化函数外部对打印位置的第二次调用失败。我有一种感觉,在初始化函数中创建的数组对象被破坏,无法传递,但我不确定,也不知道如何修复它 任何帮助都将不胜感激 #include <iostream> #include <iomanip> #include <string>

我试图创建一个指向类对象的空指针,并在函数中初始化它。不幸的是,该类的数组成员无法逃逸函数,即初始化后无法访问该函数

在下面的代码中,对打印位置的第一次调用(在初始化函数内部)工作正常,但是,从初始化函数外部对打印位置的第二次调用失败。我有一种感觉,在初始化函数中创建的数组对象被破坏,无法传递,但我不确定,也不知道如何修复它

任何帮助都将不胜感激

#include <iostream>
#include <iomanip>
#include <string>


class Atoms
{
    double * positions;
    int nAtoms;

    public:
        // Standard constructor prividing a pre-existant array
        Atoms(int nAtoms, double * positionsArray)
        {
            this->nAtoms = nAtoms;
            this->positions = positionsArray;
        }

        // Print positions to screen
        void print_positions()
        {
            std::cout<< "nAtoms: " << this->nAtoms << std::endl;
            int nDim = 3;
            for (int i = 0; i < nAtoms; i++)
            {
                for (int j = 0; j < nDim; j++)
                {
                    std::cout << std::setw(6) << this->positions[i * nDim + j] << " ";
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }

};


void initialize_Atoms_void_pointer(void ** voidAtomsPointer)
{
    //Create a new instance of Atoms by a pointer
    int numAtoms = 5;
    int numDim = 3;
    int elemN = numAtoms * numDim;
    double data_array[elemN];

    for (int i = 0; i < numAtoms; i++)
    for (int j = 0; j < numDim; j++)
    {
        data_array[i * numDim + j] = i * numDim + j + 10;
    }
    Atoms *atoms = new Atoms(numAtoms, data_array);

    // Set the vPointer that the void pointer points to a pointer to Atoms object
    *voidAtomsPointer = static_cast<void *>(atoms);

    //Test call
    std::cout << std::endl << "Initializing atoms" << std::endl;
    static_cast<Atoms *>(*voidAtomsPointer)->print_positions();
}


void print_Atoms_pointer_positions(void * voidAtomsPointer)
{
    //Cast the pointer as an atoms pointer
    Atoms *atomsPointer = static_cast<Atoms *>(voidAtomsPointer);

    atomsPointer->print_positions();
}

int main()
{
    //Use the initializer function for getting a pointer
    void *testVoidAtomsPointer;

    initialize_Atoms_void_pointer(&testVoidAtomsPointer);
    print_Atoms_pointer_positions(testVoidAtomsPointer);
}
#包括
#包括
#包括
类原子
{
双*位置;
int nAtoms;
公众:
//具有预存在数组特权的标准构造函数
原子(整数纳托姆,双*位置射线)
{
此->nAtoms=nAtoms;
此->位置=位置数组;
}
//在屏幕上打印位置
作废打印位置()
{
问题在于

Atoms *atoms = new Atoms(numAtoms, data_array);
data\u array
是一个本地数组,当
initialize\u Atoms\u void\u指针退出时,该数组将被销毁

不要复制原始指针,而是在
Atoms
的构造函数中进行新分配并复制内容:

Atoms(int nAtoms, double * positionsArray)
{
  this->nAtoms = nAtoms;
  this->positions = new double[nAtoms];
  for (int ii = 0; ii < nAtoms; ++ii)
    this->positions[ii] = positionsArray[ii];
}

~Atoms()
{
  delete[] this->positions;
}
您还需要检查
nAtoms
是否为0或负值,输入数组是否为null,等等,但我认为它不在问题的范围之内

如果需要访问原始指针,可以使用
positions.get()
方法(不要尝试删除它,否则应用程序将因双重删除而崩溃)

更新

当然,另一个更简单的解决方案是使用
std::vector

#包括
类原子{
std::向量位置;
//int nAtoms;--不再需要
公众:
原子(整数纳托姆,双*位置射线):
职位(nAtoms){
对于(int ii=0;ii位置[ii]=位置数组[ii];
}
// ...
};
如果需要访问原始指针,可以使用
positions.data()
方法(不要尝试删除它,否则应用程序将因双重删除而崩溃)。可以使用
positions.size()
检查原子数


如注释中所述,如果
Atoms
类的唯一目的是存储double,而不是添加任何其他操作,那么就忘了它,直接使用
std::vector

除了数组是局部的这一核心问题外,另一个问题是
elemN
不是编译时常量exp这很容易通过添加
const
new
void*
来解决。甚至C++98也有
std::vector
,并且C++11引入了
std::shared\U ptr
。这段代码真的很痛苦,因为它很糟糕地重新发明了轮子。谢谢你的建议。U不幸的是,在这个问题上,我只限于使用非常基本的工具。
#include <memory>

class Atoms {
  std::unique_ptr<double[]> positions;
  // ...

public:
  Atoms(int nAtoms, double * positionsArray) :
    positions(new double[nAtoms]) {
    this->nAtoms = nAtoms;
    for (int ii = 0; ii < nAtoms; ++ii)
      this->positions[ii] = positionsArray[ii];        
  }

  // ...
};
#include <vector>

class Atoms {
  std::vector<double> positions;
  // int nAtoms; -- no longer necessary

public:
  Atoms(int nAtoms, double * positionsArray) :
    positions(nAtoms) {
    for (int ii = 0; ii < nAtoms; ++ii)
      this->positions[ii] = positionsArray[ii];      
  }

  // ...
};