我使用哪种演员?

时间:2010-04-14 18:40:12

标签: c++ casting

我试图从一个对象中抛弃const,但它不起作用。但是如果我使用旧的C-way代码编译。那么我想用哪种铸造来达到同样的效果呢?我不想抛弃旧的方式。

//file IntSet.h

#include "stdafx.h"
#pragma once
/*Class representing set of integers*/
template<class T>
class IntSet
{
private:
    T** myData_;
    std::size_t mySize_;
    std::size_t myIndex_;
public:
#pragma region ctor/dtor
    explicit IntSet();
    virtual ~IntSet();
#pragma endregion
#pragma region publicInterface
    IntSet makeUnion(const IntSet&)const;
    IntSet makeIntersection(const IntSet&)const;
    IntSet makeSymmetricDifference(const IntSet&)const;
    void insert(const T&);

#pragma endregion
};

//file IntSet_impl.h

#include "StdAfx.h"
#include "IntSet.h"

#pragma region ctor/dtor
template<class T>
IntSet<T>::IntSet():myData_(nullptr),
                    mySize_(0),
                    myIndex_(0)
{
}

IntSet<T>::~IntSet()
{
}
#pragma endregion

#pragma region publicInterface
template<class T>
void IntSet<T>::insert(const T& obj)
{
    /*Check if we are initialized*/
    if (mySize_ == 0)
    {
        mySize_ = 1;
        myData_ = new T*[mySize_];
    }
    /*Check if we have place to insert obj in.*/
    if (myIndex_ < mySize_)
    {//IS IT SAFE TO INCREMENT myIndex while assigning?
        myData_[myIndex_++] = &T(obj);//IF I DO IT THE OLD WAY IT WORKS
        return;
    }

    /*We didn't have enough place...*/
    T** tmp = new T*[mySize_];//for copying old to temporary basket
    std::copy(&myData_[0],&myData_[mySize_],&tmp[0]);

}
#pragma endregion

感谢。

5 个答案:

答案 0 :(得分:4)

有一个专用的C ++强制转换运算符来处理const:const_cast

myData_[myIndex_++] = &const_cast<T>(obj);

答案 1 :(得分:2)

我认为这就是你所指的:

    myData_[myIndex_++] = &T(obj);//IF I DO IT THE OLD WAY IT WORKS

这不是演员表达。 T(obj)构造一个临时对象,&获取它的地址,这是非法的。您不能存储指向临时的指针,因为它在执行到下一个;时消失。

这里的问题不是强制转换,而是你的结构如何从根本上存储数据。你想制作一个可修改的副本,由结构拥有吗?或者您想引用由其他东西管理的外部数据?

如果您希望结构实际包含它返回的数据,您可以执行类似

的操作
    myData_[myIndex_++] = new T(obj);

(但请记住以后delete。)如果你想引用外部数据,但又能修改它,你想要

void IntSet<T>::insert(T& obj) // remove const

如果您想要对外部数据进行不可修改的引用,那么

T const ** myData_;

将删除删除常量的必要性。 (但请注意,这会使insert(3)之类的内容崩溃。)

然而

使用C ++的内置工具会好得多。不要使用IntSetMakeUnionmakeIntersection实施makeSymmetricDifference,而是使用已排序的std::vector<int>和/或std::set<int>std::set_unionstd::set_intersectionstd::set_symmetric_difference

答案 2 :(得分:1)

问题不在于演员。如果你真的打算存储一个常量对象,那么相应地声明你的数组,例如:

T const ** myData_;

如果由于您实际上需要稍后修改数据而无法实现,那么您应该复制参数或重新检查您的界面,因为它现在表示您不会修改参数。

答案 3 :(得分:0)

你确定要这么做吗?为什么要存储指向传入的整数而不是整数本身的指针?

您很有可能存储指向临时的指针; const T& obj可以从可转换为T的类型创建为临时值。例如,如果您有以下内容:

IntSet<int> int_set;
int_set.insert(1);
short foo= 2;
int_set.insert(foo);

IntSet<T>::insert的两次调用都会导致存储指向临时值的指针,这几乎总是一个错误。

答案 4 :(得分:-1)

以下功能有什么问题?

int * foo(){int x = 3;返回&amp; x; }

x存在于哪里?当foo返回x发生的事情?我认为在开始使用模板和通用编程之前,你需要学习基础知识。