如何初始化一个指向未知大小的const数据的const指针(需要alloc)

时间:2015-06-21 08:12:04

标签: c++ pointers constructor const

我有以下课程:

class A {
    A(B* b, unsigned int size_in);
private:

    unsigned int size;

    // Pointer whose address and pointed-to data shouldn't be changed
    const char* const p1;

    // Pointer which should hold a copy of p1's data (at another location in the memory).
    // Shouldn't ever be changed once copied from p1
    const char* const p1_copy;
};

我试图理解我应该如何构建构造函数,我想要一些这样的功能:

A::A(B* b, unsigned int size_in) :
  size(size_in), p1(b->GetPtr() + b->GetOffset())
{
  p1_copy = new char[size];
  memcpy(p1_copy, p1, size);
}

但我显然不能对p1_copy这样做,因为它是const并且只能在初始化列表中初始化(同样memcpy也不能用const指针作为第一个参数)

执行构造函数后

FYI:,我永远不会更改p1p1_copy

这样做的正确方法是什么?

谢谢!

3 个答案:

答案 0 :(得分:1)

可能有一些不同的解决方案,但这是const_cast设计的典型案例 - 您暂时想要覆盖某些内容的const

所以,你想要的东西(它可以在没有临时变量的情况下完成,但你需要更多的const_cast操作,而且它不那么清晰。

  char* tmp = new char[size];
  memcpy(tmp, p1, size);
  const_cast<const char*>(p1_copy) = tmp;

答案 1 :(得分:1)

一个选项可能是创建一个复制字符串的函数:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">


    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true">

        <TableRow>
            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView1"
                android:layout_row="0"
                android:layout_column="0"
                android:src="@drawable/img1"/>

            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView2"
                android:layout_row="0"
                android:layout_column="1"
                android:src="@drawable/img2"/>
        </TableRow>
        <TableRow>
            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView3"
                android:layout_row="1"
                android:layout_column="0"
                android:src="@drawable/img3"/>

            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView4"
                android:layout_row="1"
                android:layout_column="1"
                android:src="@drawable/img4"/>
        </TableRow>
        <TableRow>
            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView5"
                android:layout_row="2"
                android:layout_column="0"
                android:src="@drawable/img5"/>

            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView6"
                android:layout_row="2"
                android:layout_column="1"
                android:src="@drawable/img6"/>
        </TableRow>
        <TableRow>
            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView7"
                android:layout_row="3"
                android:layout_column="0"
                android:src="@drawable/img7"/>

            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView8"
                android:layout_row="3"
                android:layout_column="1"
                android:src="@drawable/img8"/>
        </TableRow>
        <TableRow>
            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView9"
                android:layout_row="4"
                android:layout_column="0"
                android:src="@drawable/img9"/>

            <ImageView
                android:layout_width="150dp"
                android:layout_height="200dp"
                android:id="@+id/imageView10"
                android:layout_row="4"
                android:layout_column="1"
                android:src="@drawable/img10"/>
        </TableRow>

    </TableLayout>
</RelativeLayout>

我更喜欢的另一个选择是使用char* copyString(const char* s, size_t size) { char* copy = new char[size]; memcpy(copy, s, size); return copy; } A::A(B* b, unsigned int size_in) : size(size_in), p1(b->GetPtr() + b->GetOffset()), p1_copy(copyString(p1, size_in)) { } 而不是原始指针:

std::string

答案 2 :(得分:0)

不确定这是否是正确/最好的方式,但你不能做像

这样的事情
class A {
    //...
    const std::string p1_copy;
};

A::A(B* b, unsigned int size_in) :
  size(size_in), p1(b->GetPtr() + b->GetOffset()),
  p1_copy(p1, p1 + size_in)
{
}

然后

const char* copy(const char* a, int size) {
    const char* ret = new char[size];
    memcpy(ret, a, size);
    return ret;
}