我想尝试使用返回类型const MyClass * const.但是,我收到警告:
警告:#815-D:返回类型的类型限定符无意义.
这不是有效的类型吗?我想要一个无法改变的指针,我希望它指向的东西也不会改变.
我试图了解返回const引用是否有任何好处.我有一个通常看起来像这样的阶乘函数:
unsigned long factorial(unsigned long n)
{
return (n == 0) ? 1 : n * factorial(n - 1);
}
Run Code Online (Sandbox Code Playgroud)
我假设当我们通过const引用传递并且返回const引用时会有性能提升......但是 - const正确性总是让我感到困惑.
const unsigned long & factorial(const unsigned long& n)
{
return (n == 0) ? 1 : n * factorial(n - 1);
}
Run Code Online (Sandbox Code Playgroud)
返回const引用是否有效?还有,有人可以告诉我:这有益吗?
最近我发现了一段有效执行以下操作的C++代码:
char* pointer = ...;
const char* constPointer = const_cast<const char*>( pointer );
Run Code Online (Sandbox Code Playgroud)
显然作者认为这const_cast意味着"添加const",但实际上const也可以隐含地添加:
const char* constPointer = pointer;
Run Code Online (Sandbox Code Playgroud)
有没有当我真的有任何情况下const_cast ,以一个指针到常量(const_cast<const Type*>如上面的例子)?
在C++中,可以在堆上分配const对象:
const Class* object = new const Class();
const_cast<Class*>( object )->NonConstMethod(); // UB
Run Code Online (Sandbox Code Playgroud)
因此,写入对象的尝试将是UB.
我不知道这样的对象将如何与未声明的堆分配对象不同const:
const Class* object = new Class();
Run Code Online (Sandbox Code Playgroud)
我的意思是当我在堆栈上分配一个对象时,它会转到自动存储,这是特定于实现的,所以可能有一些特定const于实现的方法允许以某种特殊方式分配对象,当我写入对象时会产生UB.
然而,每当我使用new编译器时,都需要发出operator new()函数调用,并且该函数不可能做任何不同的事情 - 它只是以统一的方式分配内存,无论const我的代码中是否存在.
一个是如何const堆上分配的对象从非不同的const一个,如何是不确定的行为可能的,如果我尝试修改呢?
c++ memory-management const const-correctness undefined-behavior
使用案例:
class A {
static int s_common;
public:
static int getCommon () const { s_common; };
};
Run Code Online (Sandbox Code Playgroud)
通常,这会导致错误:
错误:静态成员函数'static int A :: getCommon()'不能有cv-qualifier
这是因为constness仅适用于指向的对象this,而该对象在static成员函数中不存在.
但是如果允许的话,static成员函数的"const"可能很容易与static数据成员相关.
为什么C++中不存在此功能; 它背后的任何逻辑原因?
如果是这样,为什么一些Win32标头使用它?
例如:
BOOL APIENTRY VerQueryValueA( const LPVOID pBlock,
LPSTR lpSubBlock,
LPVOID * lplpBuffer,
PUINT puLen
);
Run Code Online (Sandbox Code Playgroud)
多一点的阐述:如果API从不使用引用(或任何其他C++ -只建),但只有指针和价值观,什么是具有点const LPVOID对LPCVOID.
我应该把每个地方都const LPVOID视为真正含义的地方LPCVOID吗?(因此添加演员是安全的)
进一步澄清:const LPVOID pBlock在这种情况下,这似乎确实是一个错误.Windows 2008的SDK它替换到LPCVOID的VerQueryValue签名.很久以前,葡萄酒就这么做了.
有许多问题讨论了处理指针到const删除的C和C++的细节,即free()不接受它们的那些delete和delete[]那样做,并且该const不会阻止对象破坏.
我感兴趣的是你是否认为这是一个好习惯,而不是语言(C和C++)允许的.
指针到const删除的参数包括:
kfree()与C's不同free(),Linus Torvalds 采取了一种void const*观点,因为他认为释放记忆不会影响指向的内容.free() 是在引入const关键字之前设计的.反对它的论据包括:
请在您的回复中充分说明,并可能参考当局.我的意图不是在这里开始民意调查.
我试图向const一些新代码介绍一些正确性(实际上是函数范例),并发现我无法将std::shared_ptr<A>一个函数传递给期望的函数std::shared_ptr<A const>.请注意,我不想抛弃 const而是引入它,这对于原始指针是合法的.
有办法解决这个问题吗?我没有找到成员函数来执行此操作.
g ++ 4.6.1发出的确切错误是:
error: no matching function for call to ‘foo(std::shared_ptr<A>)’
note: candidate is:
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>)
Run Code Online (Sandbox Code Playgroud) 使用decltype和std::is_const可以从外部检测变量的常量.但是对象是否也可以知道它自己的常量?用法应该是:
#include <type_traits>
#include <iostream>
#include <ios>
struct Test
{
Test() {}
bool print() const
{
// does not work as is explained in https://stackoverflow.com/q/9890218/819272
return std::is_const<decltype(*this)>::value; // <--- what will work??
}
};
int main()
{
Test t;
const Test s;
// external constness test
std::cout << std::boolalpha << std::is_const<decltype(t)>::value << "\n";
std::cout << std::boolalpha << std::is_const<decltype(s)>::value << "\n";
// internal constness test
std::cout << std::boolalpha << t.print() << "\n";
std::cout << std::boolalpha …Run Code Online (Sandbox Code Playgroud) 我有一个包含一些指针的结构.我希望这些价值不可修改.但是简单地编写const infront并不会使结构成员不可靠
typedef struct{
int *x;
int *y;
}point;
void get(const point *p,int x, int y){
p->x[0]=x;//<- this should not be allowed
p->y[0]=y;//<- this should not be allowed
}
Run Code Online (Sandbox Code Playgroud)
有人能指出我正确的方向.
编辑:
因此,似乎没有简单的方法来使用函数原型来告诉属于该结构的所有内容都应该是不可修改的
c++ ×9
const ×3
c ×2
c++11 ×2
casting ×1
constants ×1
reference ×1
reflection ×1
shared-ptr ×1
type-traits ×1
typedef ×1
winapi ×1