我是Java的新手,我对于对象分配有一些问题.例如,
Test t1 = new Test();
Test t2 = t1;
t1.i=1;
Run Code Online (Sandbox Code Playgroud)
假设变量i的测试类中定义的,我说得对假设T1和T2点到修改同一个对象t1.i=1会影响t1和t2?实际上我测试了它,看起来我是对的.但是,当我尝试相同的操作时String,修改仅发生在另一侧不受影响的一侧.这背后的原因是什么?
编辑:我尝试使用String的情况.
String s1 = "0";
String s2 = s1;
s1 = "1";
System.out.println(s1);
System.out.println(s2);
Run Code Online (Sandbox Code Playgroud)
我通过测试String上的案例来实现我的错误,因为它是不可变的.我认为s1="1"修改字符串的情况实际上是将"1"的引用返回给s1.不过,我的问题仍然存在.是否Test t2 = t1;导致t2和t1指向同一个对象,或者现在每个都有自己的对象?这种情况是否适用于Java上的所有对象?
C#:你可以这样做,以便方法参数通过引用传递一个对象但是只读吗?
例如:
void MyMethod(int x, int y, read-only MyObject obj)
Run Code Online (Sandbox Code Playgroud)
where obj是对象引用,但在方法期间无法修改此对象.
这可以用C#实现吗?
让我们说我认识一个不熟悉C++的人.他没有绕过指针(正确地说是这样),但他拒绝通过引用传递.他总是使用传值.原因是他觉得"通过引用传递物体是一种破碎设计的标志".
该程序是一个小型图形程序,大多数传递的问题是数学Vector(3元组)对象.有一些大的控制器对象,但没有比这复杂.
我发现很难找到一个反对只使用堆栈的杀手论点.
我认为按值传递对于诸如向量之类的小对象是好的,但即使这样,代码中也会发生许多不必要的复制.按值传递大型对象显然是浪费,很可能不是您想要的功能.
在专业方面,我相信堆栈在分配/解除分配内存方面更快,并且具有恒定的分配时间.
我能想到的唯一主要论点是堆栈可能会溢出,但我猜这是不可能发生的?是否有任何其他参数反对仅使用堆栈/传递值而不是通过引用传递?
我在类之间有一些"setter"方法,为方便起见,我添加了一个可选参数$previous,它通过引用获取参数,并在用新值替换之前用现有值填充它.例如:
public function set_value($key, $value, &$previous = null)
{
$previous = $this->get_value($key);
$this->_values[$key] = $value;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
这很好用; 但是在某些情况下,相应的"getter"方法有点过程密集,无条件运行它是一种浪费.我想我可以测试:
if(null !== $previous)
{
$previous = $this->get_value($key);
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为通常作为参数传递的变量$previous先前未在其范围中定义,并且无论如何都默认为null.我遇到的唯一解决方案是:
public function set_value($key, $value, &$previous = null)
{
$args = func_get_args();
if(isset($args[2])
{
$previous = $this->get_value($key);
}
$this->_values[$key] = $value;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
或者,一行:
if(array_key_exists(2, func_get_args()))
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢方法体依赖于参数索引(当它看起来应该是不必要的时候)有没有更清晰的方法来实现我在这里之后的东西?
我试过了:
if(isset($previous)){}
if(!empty($previous)){}
if(null !== $previous){}
Run Code Online (Sandbox Code Playgroud)
都没有工作.
迄今可能的解决方案:
if(func_num_args() == $num_params){}
if(array_key_exists($param_index, func_get_args())){}
// …Run Code Online (Sandbox Code Playgroud) public class program1{
public static void main(String args[]){
java.util.Vector vc=new java.util.Vector();
vc.add("111");
vc.add("222");
functioncall(vc);
vc.add("333");
System.out.println(vc);
}
public static void functioncall(java.util.Vector vc){
vc=null;
}
}
Run Code Online (Sandbox Code Playgroud)
上述程序的输出为[111,222,333].但是,当我运行以下程序时,输出为[333].当我们传递引用时会感到困惑,无论是按值调用还是按引用调用,它是如何工作的?为什么
public class program1{
public static void main(String args[]){
java.util.Vector vc=new java.util.Vector();
vc.add("111");
vc.add("222");
functioncall(vc);
vc.add("333");
System.out.println(vc);
}
public static void functioncall(java.util.Vector vc){
vc.removeAllElements();
}
}
Run Code Online (Sandbox Code Playgroud) 考虑:
#include <iostream>
using namespace std;
void Change(int arr[3]) {
for (int i = 0; i < 3; i++) {
arr[i] = 1;
}
}
int Test() {
int arr[3] = { 0, 0, 0 };
for (int i = 0; i < 3; i++) {
cout << arr[i] << endl;
}
Change(arr);
for (int i = 0; i < 3; i++) {
cout << arr[i] << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于数组默认作为指向其第一个元素的指针传递并且不会被复制,因此在函数中更改数组元素的值实际上会导致在函数调用者中更改数组该元素的值,这就是为什么以上代码输出
#include <iostream>
using namespace std;
void Change(int …Run Code Online (Sandbox Code Playgroud) 给出以下方法:
static void ChangeArray(params string[] array) {
for (int i = 0; i < array.Length; i++)
array[i] = array[i] + "s";
}
Run Code Online (Sandbox Code Playgroud)
如果我调用它传递一个字符串数组,这是有效的:
string[] array = {"Michael", "Jordan"} // will become {"Michaels", "Jordans"}
ChangeArray(array);
Run Code Online (Sandbox Code Playgroud)
但如果我使用字符串参数调用它将无法工作:
string Michael = "Michael";
string Jordan = "Jordan";
ChangeArray(Michael, Jordan); // This will NOT change the values of the variables
Run Code Online (Sandbox Code Playgroud)
我知道编译器会将Michael和Jordan包装在一个数组上,所以两种情况下结果不一样吗?
在C#中,我知道默认情况下,传递给函数的任何参数都是通过复制的,即在函数内,有一个参数的本地副本.但是,当一个对象作为参数传递给另一个类时呢?
是否会通过引用或值传递以下方案:
class MyClass {
private Object localObj;
public void SetObject(Object obj) {
localObj = obj;
}
}
void Main() {
Object someTestObj = new Object();
someTestObj.name = "My Name";
MyClass cls = New MyClass();
cls.SetObject(someTesetObj);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,类变量localObj是否someTestObj与Main驱动程序类中创建的副本相同?或者两个变量是否指向不同的对象实例?
我有一个函数,我必须修改向量的值.返回向量是C++的一个好习惯吗?
vector<string> RemoveSpecialCharacters(vector<string> words)
{
for (vector<string>::iterator it=words.begin(); it!=words.end(); )
{
if(CheckLength(*it) == false)
{
it = words.erase(it);
}
else{
++it;
}
}//end for
return words;
}
Run Code Online (Sandbox Code Playgroud)
void RemoveSpecialCharacters(vector<string> & words)
{
for (vector<string>::iterator it=words.begin(); it!=words.end(); )
{
if(CheckLength(*it) == false)
{
it = words.erase(it);
}
else{
++it;
}
}//end for
}
Run Code Online (Sandbox Code Playgroud) 在下面的代码中,我无法将临时对象作为参数传递给printAge函数:
struct Person {
int age;
Person(int _age): age(_age) {}
};
void printAge(Person &person) {
cout << "Age: " << person.age << endl;
}
int main () {
Person p(50);
printAge(Person(50)); // fails!
printAge(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
error: invalid initialization of non-const reference of type ‘Person&’ from an rvalue of type ‘Person’
Run Code Online (Sandbox Code Playgroud)
我意识到这与将lValue传递给期望rValue的函数有关...有没有办法通过使用std :: move或其他东西将我的lValue转换为rValue?我尝试了一个常量参数,但这似乎不起作用.