我理解为一堂课
class A {
const int myint;
public:
A (const int yourint);
A (const std::string yourstring);
};
Run Code Online (Sandbox Code Playgroud)
我可以myint在初始化列表中初始化,如下所示:
A::A (const int yourint) : myint (yourint) {};
Run Code Online (Sandbox Code Playgroud)
但是,myint如果计算它所需的数据来自字符串并且可能涉及计算,那么从第二个构造函数初始化的正确方法是什么?
来自C++背景,我习惯于将const关键字粘贴到函数定义中,以使对象以只读值传递.但是,我发现在C#中这是不可能的(如果我错了请纠正我).经过一些谷歌搜索后,我得出的结论是,制作只读对象的唯一方法是编写一个只有'get'属性并将其传入的接口.优雅,我必须说.
public interface IFoo
{
IMyValInterface MyVal{ get; }
}
public class Foo : IFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
}
}
Run Code Online (Sandbox Code Playgroud)
我会把它传递给:
public void SomeFunction(IFoo fooVar)
{
// Cannot modify fooVar, Excellent!!
}
Run Code Online (Sandbox Code Playgroud)
这可以.但是,在我的其余代码中,我想正常修改我的对象.向接口添加"set"属性会破坏我的只读限制.我可以添加一个'set'属性Foo(而不是IFoo),但签名需要一个接口而不是一个具体的对象.我不得不做一些铸造.
// Add this to class Foo. Might assign null if cast fails??
set { _myVal = value as ConcreteMyVal; }
// Somewhere else in the code...
IFoo myFoo = new Foo; …Run Code Online (Sandbox Code Playgroud) 在将对象的新实例传递给具有对象类实现的接口的const接口参数的方法时,编译器是否应该提示/警告?
编辑:当然样本很容易说明问题.但在现实生活中,它变得更加复杂:如果创建和使用在相隔很远的代码(不同的单元,不同的类,不同的项目)中会怎么样?如果由不同的人维护怎么办?如果非const参数变为常量参数,并且不能检查所有调用代码(因为更改代码的人无法访问所有调用代码),该怎么办?
下面的代码崩溃了,很难找到原因.
首先是日志:
1.Run begin
1.RunLeakCrash
2.RunLeakCrash begin
NewInstance 1
AfterConstruction 0
3.LeakCrash begin
_AddRef 1
4.Dump begin
4.Dump Reference=10394576
4.Dump end
_Release 0
_Release Destroy
BeforeDestruction 0
3.LeakCrash Reference got destroyed if it had a RefCount of 1 upon entry, so now it can be unsafe to access it
_AddRef 1
4.Dump begin
4.Dump Reference=10394576
4.Dump end
_Release 0
_Release Destroy
BeforeDestruction 0
3.LeakCrash end with exception
1.Run end
EInvalidPointer: Invalid pointer operation
Run Code Online (Sandbox Code Playgroud)
然后过早释放实现接口的对象实例的代码:
//{$define all} …Run Code Online (Sandbox Code Playgroud) 我收到这个奇怪的错误:
错误C2663:'sf :: Drawable :: SetPosition':2个重载没有'this'指针的合法转换
我认为它与const不匹配有关,但我不知道在哪里或为什么.在下面的代码中,我有一个形状和精灵的向量,当试图访问其中一个向量形状并调用其中一个函数时,我得到了错误.
std::vector<sf::Shape> Shapes;
std::vector<sf::Sprite> Sprites;
bool AddShape(sf::Shape& S){
Shapes.push_back(S); return true;
};
bool AddSprite(sf::Sprite& S){
Sprites.push_back(S); return true;
};
private:
virtual void Render(sf::RenderTarget& target) const {
for(unsigned short I; I<Shapes.size(); I++){
Shapes[I].SetPosition(
Shapes[I].GetPosition().x + GetPosition().x,
Shapes[I].GetPosition().y + GetPosition().y);
target.Draw(Shapes[I]);
}
for(unsigned short I; I<Sprites.size(); I++){
target.Draw(Sprites[I]);
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
在具有泛型类型T的C++模板中,我可以使用
const T &
Run Code Online (Sandbox Code Playgroud)
获取对常量T的引用.但是,如果现在T本身是引用类型(例如T = int&),则上述术语解析为
int &
Run Code Online (Sandbox Code Playgroud)
而不是
const int &
Run Code Online (Sandbox Code Playgroud)
这很有意义,因为任何引用本身都是不变的.但是,还有一种方法需要一个
const T &
Run Code Online (Sandbox Code Playgroud)
如果T本身是参考类型?
编辑:要评估的示例代码(g ++编译器):
template <typename T> class TemplateClass
{
public:
void foo(const T &bar) { }
};
int main()
{
TemplateClass<int &> x;
x.foo(0); // <-- compile error: no conversion from int to int&
return 0;
}
Run Code Online (Sandbox Code Playgroud) 当然,这不会编译:
int &z = 3; // error: invalid initialization of non-const reference ....
Run Code Online (Sandbox Code Playgroud)
这将编译:
const int &z = 3; // OK
Run Code Online (Sandbox Code Playgroud)
现在,考虑一下:
const int y = 3;
int && yrr = y; // const error (as you would expect)
int && yrr = move(y); // const error (as you would expect)
Run Code Online (Sandbox Code Playgroud)
但这些下一行确实为我编译.我认为不应该.
int && w = 3;
int && yrr = move(3);
void bar(int && x) {x = 10;}
bar(3);
Run Code Online (Sandbox Code Playgroud)
最后两行不会允许文字3被修改吗?3与const int有什么区别?最后,"修改"文字是否有任何危险?
(g ++ - 4.6(GCC)4.6.2 with …
const关键字在此模板中的作用是什么?
template <class T, int const ROWNUM, int const COLNUM>
class Matrix
Run Code Online (Sandbox Code Playgroud)
这是否意味着此模板仅接受constas参数?如果是这样,有没有办法将变量作为COLNUM和ROWNUM?
(当我尝试将变量作为模板的COLNUM传递时,它会出错:"IntelliSense:expression必须具有常量值")
是否可以使用类似于generate_n创建const vector随机数字的东西?如果没有vector在构造函数中派生和执行赋值,我无法想到这样做的方法.
我是C++的新手.我读过的这本书告诉我,如果+为某个类对象(比如类)重载了plus()运算符,那么string这个问题会更加具体.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("abc");
string s2("def");
string s3("def");
cout<<(s1+s2=s3)<<endl;
int x=1;
int y=2
int z=3;
cout<<(x+y=z)<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您所料,第一个cout陈述是正确的,而第二个陈述是错误的.编译器投诉x+y不是可修改的左值.我的问题是为什么+操作符为string对象返回可修改的左值但不是为了int?
我一直认为这const char **x是一个正确的类型,用于动态分配的const字符串数组,如下所示:
#include <stdlib.h>
int main()
{
const char **arr = malloc(10 * sizeof(const char *));
const char *str = "Hello!";
arr[0] = str;
free(arr);
}
Run Code Online (Sandbox Code Playgroud)
但是,在使用VS2017编译此代码时,我会收到此警告free:
warning C4090: 'function': different 'const' qualifiers
Run Code Online (Sandbox Code Playgroud)
我的代码有问题吗?FWIW,当我和GCC一起编译时,即使有了,也没有任何警告-Wall -Wextra -pedantic.