我是Swift的新手,我只是读取类通过引用传递,数组/字符串等被复制.
通过引用传递的方式与Objective-C或Java中的方式相同,其中您实际传递"a"引用或是否通过引用正确传递?
一个简单的问题,我在这里找不到答案.
我理解的是,在调用期间将参数传递给函数,例如
void myFunction(type myVariable)
{
}
void main()
{
myFunction(myVariable);
}
Run Code Online (Sandbox Code Playgroud)
对于像int,float等等的简单数据类型,函数由值调用.
但是如果myVariable是数组,则只传递起始地址(即使我们的函数是值函数调用).
如果myVariable是对象,则也只传递对象的地址,而不是创建副本并传递它.
所以回到这个问题.C++是通过引用还是值传递对象?
让我们考虑一个对象foo(可能是一个int,一个double,一个习惯struct,一个class,等等).我的理解是,通过foo引用函数(或只是传递指针foo)来传递更高的性能,因为我们避免制作本地副本(如果foo很大则可能很昂贵).
但是,从这里的答案来看,似乎64位系统上的指针实际上可以预期大小为8字节,无论指向什么.在我的系统上,a float是4个字节.这是否意味着如果foo是类型float,那么仅通过值传递而不是给它指向它是更有效的foo(假设没有其他约束可以使得使用一个比函数内的另一个更有效)?
c++ pointers pass-by-reference pass-by-value pass-by-pointer
我从未使用过std::get_if,并且由于它的名称与 不同std::get,我看不出为什么它的参数应该是指针\xc2\xb9 (而std::get有一个按引用参数)。
\xc2\xb9如果它也被命名std::get,那么重载解析就足够了。
是的,我的问题可能会被欺骗到问题 std::any_cast() 和 std::get_if(std::variant) 是否绝对有必要将指针作为参数?,但关键是没有答案解决std::get_ifvs std::get,只有一个评论;唯一的答案集中在std::any_cast。
假设我有一个这样的程序:
#include <iostream>
#include <string>
#include <vector>
// Takes values and outputs a string vector.
std::vector<std::string> foo(const int argc, char* args[]) {
std::vector<std::string> strings;
for (int i = 0; i < argc; i++)
strings.push_back(args[i]);
return strings;
}
int main(int argc, char *args[]) {
std::vector<std::string> strings = foo(argc, args);
for (unsigned int i = 0; i < strings.size(); i++)
std::cout << strings[i] << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我要尝试将main()函数的char**参数传递给另一个函数或类.(我知道有更好的方法可以实现上述程序的功能,我的问题是将char**参数作为只读方式传递).
问题:
不确定标题中的术语是否 100% 正确,但我的意思很容易通过这个例子来说明:
class MyClass{
String str = '';
MyClass(this.str);
}
void main() {
MyClass obj1 = MyClass('obj1 initial');
print(obj1.str);
doSomething(obj1);
print(obj1.str);
doSomethingElse(obj1);
print(obj1.str);
}
void doSomething(MyClass obj){
obj.str = 'obj1 new string';
}
void doSomethingElse(MyClass obj){
obj = MyClass('obj1 new object');
}
Run Code Online (Sandbox Code Playgroud)
这将打印
obj1 initial
obj1 new string
obj1 new string
Run Code Online (Sandbox Code Playgroud)
但是,如果我想doSomethingElse()实际修改obj1引用的内容,那么输出将是:
obj1 initial
obj1 new string
obj1 new object
Run Code Online (Sandbox Code Playgroud)
这在 Dart 中是否可行,如果可以,如何实现?
我有一个函数,它接受一个结构的双指针并赋值.但是,当我尝试访问该成员时,我收到了"访问违规写入位置..." member1.这是我的代码:
struct mystruct{
unsigned int member1;
void * data;
};
int main(){
mystruct **foo = new mystruct *;
bar(foo);
}
void bar(unsigned int val, mystruct ** foo)
{
(*foo)->member1 = val;
}
Run Code Online (Sandbox Code Playgroud) 我有一个接受a的功能
vector<vector<MyClass>>
Run Code Online (Sandbox Code Playgroud)
并修改MyClass实例.自从我编写任何C++以来已经很长时间了,我很难记住通过引用而不是通过值传递整个arg的内容.
我原来的方法签名是:
void modifyVectorOfVectors(vector<vector<MyClass> > vec) { ... }
Run Code Online (Sandbox Code Playgroud)
我想让这个内存有效,所以我最初改为:
void modifyVectorOfVectors(vector<vector<MyClass*> > vec) { ... }
Run Code Online (Sandbox Code Playgroud)
然后我意识到这意味着我的vec值仍然会复制所有内部向量.所以我将我的功能签名更改为:
void modifyVectorOfVectors(vector<vector<MyClass*> >* vec) { ... }
Run Code Online (Sandbox Code Playgroud)
这是否足够,或者我还需要做以下事情:
void modifyVectorOfVectors(vector<vector<MyClass*>* >* vec) { ... }
Run Code Online (Sandbox Code Playgroud)
有人可以强调所有这些之间的记忆差异吗?非常感谢!
我正在尝试制作一个非常简单的程序来修改数组,但是如果我将它们转换为类型,则会遇到一些有趣的行为。https://play.golang.org/p/KC7mqmHuLw看来,如果我有一个数组,则按引用传递,但如果我有一个类型,则按值传递。它是否正确?
我有两个变量 b 和 c,都是 3 个整数的数组,但 c 是 cT 类型,在其他方面它们应该是相同的。我可以将值指定为b[0]=-1和c[0]=-1,但是如果我将这些数组作为参数传递给函数,它们的行为就会非常不同。
程序的输出是:
b 之前:[1 2 3]
c之前:[1 2 3]
*b 之后:[-1 2 0]
*c 之后:[-1 2 3]
*什么?c:[-1 2 0]
我最初的假设是“after b”和“after c”行应该是相同的。我是否做错了什么,或者我对按值传递给函数的类型是否正确(即在传递给函数之前创建变量的副本)?
package main
import "fmt"
type cT [3]int
func main() {
b := []int{1, 2, 3}
c := cT{1, 2, 3}
fmt.Println("before b:", b)
fmt.Println("before c:", c)
b[0] = -1
c[0] = -1
mangleB(b) // ignore return value
mangleC(c) // ignore return …Run Code Online (Sandbox Code Playgroud) parameter-passing pass-by-reference pass-by-value go pass-by-pointer
这个问题是作为这个问题的后续问题:C++中指针变量和引用变量之间有什么区别?
阅读了我在stackoverflow上找到的答案和一些进一步的讨论后,我知道编译器应该像处理pass-by-pointer一样对待pass-by-reference,而引用只不过是语法糖.考虑到二进制兼容性,如果存在任何差异,我还无法弄清楚一件事.
在我们的(多平台)框架中,我们要求在发布和调试版本之间(以及框架的不同版本之间)进行二进制兼容.特别是,我们在调试模式下构建的二进制文件必须可用于发布版本,反之亦然.为此,我们只在接口中使用纯抽象类和POD.
请考虑以下代码:
class IMediaSerializable
{
public:
virtual tResult Serialize(int flags,
ISerializer* pSerializer,
IException** __exception_ptr) = 0;
//[…]
};
Run Code Online (Sandbox Code Playgroud)
ISerializer并且IException也是纯粹的抽象类.ISerializer必须指向现有对象,因此我们总是必须执行NULL指针检查.IException实现某种异常处理,其中指针指向的地址必须改变.出于这个原因,我们使用指向指针的指针,指针也必须是NULL指针.
为了使代码更清晰并省去一些不必要的运行时检查,我们希望使用pass-by-reference重写此代码.
class IMediaSerializable
{
public:
virtual tResult Serialize(int flags,
ISerializer& pSerializer,
IException*& __exception_ptr) = 0;
//[…]
};
Run Code Online (Sandbox Code Playgroud)
这似乎没有任何缺陷.但问题仍然是我们是否仍然满足二进制兼容性的要求.
更新: 澄清事情:这个问题不是关于代码的pass-by-pointer版本和pass-by-reference版本之间的二进制兼容性.我知道这不能是二进制兼容的.事实上,我们有机会重新设计我们的API,我们考虑使用pass-by-reference而不是pass-by-pointer而不关心二进制兼容性(新的主要版本).问题只是关于仅使用代码的pass-by-reference版本的二进制兼容性.
c++ interface-design pass-by-reference binary-compatibility pass-by-pointer
pass-by-pointer ×10
c++ ×7
pointers ×2
c++17 ×1
char-pointer ×1
dart ×1
flutter ×1
go ×1
std-variant ×1
swift ×1
vector ×1