我确信以下代码不应该编译.但是,在g ++中,它确实可以编译!请参阅http://codepad.org/MR7Dsvlz编译.
代码:
#include <iostream>
using namespace std;
int main() {
int x = 32 ;
// note: if x is, instead, a const int, the code still compiles,
// but the output is "32".
const int * ptr1 = & x ;
*((int *)ptr1) = 64 ; // questionable cast
cout << x ; // result: "64"
}
Run Code Online (Sandbox Code Playgroud)
编译时g ++是错误的吗?
粗略地说,我有一个包含const unsigned char数组的类.此类的对象由特殊的工厂函数创建,该函数还负责构造数组(在堆上).在工厂函数中创建对象时,将为其指定数组.数组不会被复制,对象只会使用给定的指针.在销毁时,它将释放数组占用的内存块.
class Foo
{
private:
const unsigned char* array;
size_t size;
public:
Foo(const unsigned char* array, size_t size) : array(array), size(size) {}
~Foo() {delete [] array;}
};
Foo* factoryFunction(const void* data, size_t size)
{
unsigned char* array = new unsigned char[size];
memcpy(array, data, size);
return new Foo(array, size);
}
Run Code Online (Sandbox Code Playgroud)
现在我想知道是否有任何副作用,因为new []返回unsigned char *,但delete []需要const unsigned char *.我没有得到任何分段错误.
我正在我的Raspberry Pi上编译Percona(MySQL变体),它有一个ARM处理器.
我在报告的编译过程中遇到了一个问题,但是没有人愿意修复,因为ARM是一个不受支持的平台.
https://bugs.launchpad.net/percona-server/+bug/1002848
我已经设法解决这个问题并成功编译,但我对c ++的了解有些缺乏,而且我不完全理解我是否真的破坏了某些东西.
我已经阅读了很多关于SO的const char*到char*问题的无效转换,这是我对此解决方法的想法.
错误如下:
error: invalid conversion from 'const pthread_mutex_t*' to 'pthread_mutex_t*'
Run Code Online (Sandbox Code Playgroud)
(它实际上不在pthread_mutex_t我的平台上,但问题是相同的 - 实际类型丢失到无限深渊,即回滚缓冲区)
违规代码是:
uint32 count(uint index) const
{
my_atomic_rwlock_rdlock(&time_collector_lock);
Run Code Online (Sandbox Code Playgroud)
我改为:
uint32 count(uint index) const
{
my_atomic_rwlock_t dummy = time_collector_lock;
my_atomic_rwlock_rdlock(&dummy);
Run Code Online (Sandbox Code Playgroud)
time_collector_lock定义为:
private:
my_atomic_rwlock_t time_collector_lock;
Run Code Online (Sandbox Code Playgroud)
由于这应该是一个互斥体,我有一种感觉,我可能已经使这个非线程安全.或者这样可以吗?
有更好的解决方案吗?
这是我的问题,问题出在评论中
const int a = 5;
const_cast<int&>(a)=7; //throw over const attribute in a,and assign to 7
std::cout<<a<<std::endl; //why still out put 5!!!!!!!!!!
Run Code Online (Sandbox Code Playgroud)
谁可以告诉我为什么,有些书籍会考虑这些问题来推荐?谢谢!
出于好奇,
是否有可能派生出父成员mutable?有没有合理的方法修改以下代码并使其编译?(保留foo()方法const而int a不是mutable在父类中声明时保留方法A)
class A {
protected:
int a;
};
class B : public A {
public:
void foo() const {
a = 10;
}
};
Run Code Online (Sandbox Code Playgroud) 这是我想要使用的代码的一个简短示例:
template <class T>
class B
{
public :
bool func1(const T& t)
{
// do something
}
};
class A
{
B<int*> b;
public:
void func2(const int* a)
{
b.func1(a);
}
};
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
错误C2664:'B :: func1':无法将参数1从'const int*'转换为'int*const&'
是一种解决这个问题的方法,而无需更改函数声明和不使用const_cast?
编辑:
问题背后的一些信息
B 实际上是我写的容器类(比如列表)
A 是使用该列表的类
func1 是一个需要查找元素是否在列表中的函数
func2 是一个接收要从列表中删除的元素的函数
为C库编写C++包装器.在库中有一个接受缓冲区的函数unsigned char *.自从使用C++以来,我将我的真实缓冲区存储在std::vector<char>我也添加的包装器类中const,因为所讨论的缓冲区是一个输入缓冲区而且它不会被修改.但是我的代码没有编译,演示:
#include <stdio.h>
#include <vector>
void x(unsigned char *s)
{
printf("%s\n", s);
}
int main()
{
const std::vector<char> s(10);
x(reinterpret_cast<unsigned char *>(s.data())); // FAILS
}
Run Code Online (Sandbox Code Playgroud)
id有什么问题?如果我删除consts从const std::vector<char> s(10);它的工作原理,但我会喜欢你这样.
int main()
{
const int maxint=100;//The program will crash if this line is put outside the main
int &msg=const_cast<int&>(maxint);
msg=200;
cout<<"max:"<<msg<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果'const int maxint = 100;',该函数将运行正常.定义被放在main函数内但崩溃并弹出一条错误消息,如果放在外面则说"Access Violation".
有人说这是某种"未定义的行为",我想知道确切的答案以及如何安全地使用const转换?
当一个函数不修改一个对象参数时,我总是让它要求一个常量引用,即使引用的对象不是真正的常量.这是错的吗?
对于包装类,我想写这个:
template<class B>
class Wrapper{
private:
B* base_;
public:
Wrapper(const B& b) { base_ = const_cast<B*>(&b); }
void ModifyBase();
};
Run Code Online (Sandbox Code Playgroud)
构造函数不会修改基数,因此它要求提供常量引用.
包装器有一些方法需要修改基类,因此它需要存储一个非常量指针(因此转换).
我觉得我的解决方案不是最好的.
有一个更好的方法吗?
有没有公认的惯例?
我正在阅读关于const_cast的内容,它看起来不安全,而且不是很有帮助.在SO中关于它的最佳答案表明它在这样的场景中会有用:
void func(const char* param, bool modify){
if(modify)
//const_cast and change param
// stuff that do not change param
}
Run Code Online (Sandbox Code Playgroud)
虽然这是一种可能的用法,但它有风险,因为你必须正确地提供"修改"的值,否则你会得到一个未定义的行为,因为你正在改变应该是常量的东西.我想知道你是否可以实现相同的功能,而不必提供额外的参数,为此你很可能需要检查const限定符的存在.
我发现关闭的东西是std函数is_const,但它似乎仅限于一种不同的用法:
is_const<const int>::value //returns true
is_const<int>::value // returns false
const int myVar=1;
is_const<myVar>::value // what it would look like ( does not compile)
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用类似的功能签名,只有"const"限定符不同,但这被认为是重新定义.所以可以做到这一点吗?如果是这样,怎么办呢?
我已经知道是什么了const_cast.但是我想知道它是如何完成这项工作的.编译器在看到它时到底做了const_cast什么?
在我正在设计的库中,我有时需要对类的大型成员变量进行读取访问。由于它们的大小,我不想创建一个通过复制成员来返回的 getter。我不希望它们可以从外部修改,所以我不能将它们公开或返回对它们的引用。所以我想我会使用“阅读器”:
class TestClass
{
public:
explicit TestClass(double d): d_(d){}
const double& readD() const { return d_; }
private:
double d_;
};
Run Code Online (Sandbox Code Playgroud)
(这并不是真正适合双打的)
但这里有人可以 const_cast 引用并直接访问数据。即使没有假设恶意意图,有人也可以保护对数据成员的引用,并在原始对象超出范围后保留它。我知道 const 引用可以保持临时可行,但这并不能消除 const_cast 问题。所以我想出了一个解决方法:
#include <iostream>
template<class T>
class SafeMemberReference
{
public:
using type = T;
SafeMemberReference(const T& t) :t(t) {}
explicit SafeMemberReference(T&& t) = delete;
operator const T& () && {return t; }
T get() && {return t; }
private:
const T& t;
};
class TestClass
{
public:
explicit TestClass(double d): d_(d){}
SafeMemberReference<double> …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
int main(){
const int a = 1;
const int* b(&a);
int* c = const_cast<int*>(b);
*c = 29;
cout<<*c<<a<<*b;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
为什么'a'的值不变为29?这是否意味着当const_casting b时,a的常量不会被删除?
c++ ×13
const ×4
const-cast ×4
c++11 ×2
casting ×2
pointers ×2
arm ×1
constants ×1
conventions ×1
g++ ×1
inheritance ×1
mutable ×1
mysql ×1
percona ×1
raspberry-pi ×1
stdvector ×1
templates ×1